{"schema_version":1,"packs":[{"id":"airflow","name":"Apache Airflow","version":"0.1.4","description":"Governed Apache Airflow 3 operations over the stable REST API (/api/v2): scheduler/triggerer/dag-processor health and job heartbeats, DAG inventory and per-DAG detail, run and task-instance search across every DAG, task logs, import errors and DAG warnings, pools, asset events, connection and variable inventory (names and routing only — never values), and the incident controls an operator actually reaches for: pause and unpause a DAG, trigger a run, mark a run or task succeeded/failed, preview then perform a clear, retune a pool, and start, pause, or cancel a backfill. Authenticates with AIRFLOW_API_TOKEN, or mints a JWT from AIRFLOW_USERNAME/AIRFLOW_PASSWORD, on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/airflow","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/airflow","content_hash":"sha256:2e39322511d01fb7faa39055da5730857003e3eede6101e493d83164b6a9726a","tarball_url":"https://registry.emisar.dev/v1/packs/airflow/0.1.4/2e39322511d01fb7faa39055da5730857003e3eede6101e493d83164b6a9726a/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":["airflow"],"processes":[],"ports":[8080]},"setup":{"summary":"Every action is one HTTPS/HTTP call to the Airflow API server at `$AIRFLOW_URL` over curl on the runner host. The bearer token is sent as an Authorization header over curl stdin, and the credentials that mint one are read from the environment by jq, so neither reaches the process arguments or the audit log.","env":[{"name":"AIRFLOW_URL","description":"Base URL of the Airflow API server — scheme, host, and port. Each action appends its own path (e.g. /api/v2/dags).","default":"http://127.0.0.1:8080","example":"https://airflow.internal"},{"name":"AIRFLOW_API_TOKEN","description":"Airflow API JWT, sent as the Authorization header over curl stdin. Takes precedence over `AIRFLOW_USERNAME`/`AIRFLOW_PASSWORD`. Airflow JWTs expire ([api_auth] jwt_expiration_time, 24h by default), so a static token suits a short-lived runner; a long-lived one should carry credentials instead and let each action mint its own."},{"name":"AIRFLOW_USERNAME","description":"Airflow user whose credentials mint a JWT through POST /auth/token when `AIRFLOW_API_TOKEN` is unset. The user's own permissions gate which actions succeed — give it the least privilege the fleet needs.","example":"emisar"},{"name":"AIRFLOW_PASSWORD","description":"Password for `AIRFLOW_USERNAME`. Read from the environment by jq and posted over curl stdin; never placed in argv."}],"notes":["Any of `AIRFLOW_URL` / `AIRFLOW_API_TOKEN` / `AIRFLOW_USERNAME` / `AIRFLOW_PASSWORD` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","This pack targets the Airflow 3 API at /api/v2. Airflow 2's /api/v1 is a different surface with different auth and response shapes; point this pack at an Airflow 2 deployment and every action returns 404.","POST /auth/token is served by the simple auth manager and by the FAB provider's auth manager. A deployment behind an external identity provider that does not expose it needs `AIRFLOW_API_TOKEN` instead.","airflow.connections and airflow.variables deliberately return inventory only — connection extra fields and variable values routinely hold credentials, and no redaction pattern can be trusted to catch every shape. Read a specific value on the host with the operator's own secrets tooling.","airflow.task_log returns whatever the task wrote. Airflow's secrets masker hides known connection and variable values; anything else a task prints reaches the result.","dag_id and dag_run_id accept ~ on the search actions (airflow.dag_runs, airflow.task_instances) to search across every DAG or run — that is how you find every failed task in the fleet in one call."],"verify":"airflow.health"},"actions":[{"id":"airflow.asset_events","title":"List asset events (GET /api/v2/assets/events)","summary":"List asset update events with their timestamp and the DAG, task, and run that emitted each one. Pair with airflow.assets to answer \"when did this asset last update, and what produced it\" — the timeline behind a consumer DAG that has not triggered.","description":"List asset update events with their timestamp and the DAG, task, and run that emitted each one. Pair with airflow.assets to answer \"when did this asset last update, and what produced it\" — the timeline behind a consumer DAG that has not triggered.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/assets/events endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"asset_id","type":"integer","required":false,"default":0,"description":"Restrict to one asset by its numeric id, as reported by airflow.assets. 0 lists every asset.","validation":{"min":0,"max":9007199254740991}},{"name":"source_dag_id","type":"string","required":false,"default":"","description":"Restrict to events emitted by one DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Events returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-timestamp","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Most recent asset events","args":{}}],"search_terms":["asset event","when did the asset update","dataset event"]},{"id":"airflow.assets","title":"List assets (GET /api/v2/assets)","summary":"List the assets Airflow schedules on, with the tasks that produce them, the DAGs that consume them, and each asset's last event. In an asset-driven deployment a consumer DAG that never runs is usually waiting on a producer that stopped emitting — this read shows which one.","description":"List the assets Airflow schedules on, with the tasks that produce them, the DAGs that consume them, and each asset's last event. In an asset-driven deployment a consumer DAG that never runs is usually waiting on a producer that stopped emitting — this read shows which one.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/assets endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name_pattern","type":"string","required":false,"default":"","description":"Substring the asset name must contain. Empty lists every asset.","validation":{"pattern":"^[A-Za-z0-9._:/-]{0,250}$","max_length":250}},{"name":"dag_ids","type":"string","required":false,"default":"","description":"Comma-separated dag_ids; restricts to assets those DAGs produce or consume.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_active","type":"string","required":false,"default":"true","description":"Hide assets whose definition is gone (true, the default) or include them.","validation":{"enum":["true","false"]}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Assets returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"Every asset and its producers","args":{}}],"search_terms":["asset scheduling","data-aware scheduling","dataset","consumer dag not running"]},{"id":"airflow.backfill_cancel","title":"Cancel a backfill (PUT /api/v2/backfills/{backfill_id}/cancel)","summary":"Cancel a backfill. Its queued runs are dropped and running task instances are stopped, so a partially reprocessed date range is left partially reprocessed — which downstream consumers may read as complete. Prefer airflow.backfill_pause when the goal is only to free capacity.","description":"Cancel a backfill. Its queued runs are dropped and running task instances are stopped, so a partially reprocessed date range is left partially reprocessed — which downstream consumers may read as complete. Prefer airflow.backfill_pause when the goal is only to free capacity.","kind":"script","risk":"high","side_effects":["Stops the backfill and cancels its remaining runs.","Task instances still running are terminated mid-flight, which can leave partial writes.","The date range is left partly reprocessed; the backfill cannot be resumed."],"args":[{"name":"backfill_id","type":"integer","required":true,"description":"Backfill id, as reported by airflow.backfills.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Abandon a backfill started with the wrong range","args":{"backfill_id":7}}],"search_terms":["cancel backfill","stop backfill","kill backfill"]},{"id":"airflow.backfill_create","title":"Start a backfill (POST /api/v2/backfills)","summary":"Start a backfill of one DAG over a date range. Airflow creates one run per interval in the range and executes them for real, so a wide range is a large, sustained production load: every task writes what it normally writes and competes for the same pools as scheduled work. Bound it with max_active_runs and check airflow.backfills first.","description":"Start a backfill of one DAG over a date range. Airflow creates one run per interval in the range and executes them for real, so a wide range is a large, sustained production load: every task writes what it normally writes and competes for the same pools as scheduled work. Bound it with max_active_runs and check airflow.backfills first.","kind":"script","risk":"high","side_effects":["Creates one DAG run per interval in the range and executes every task in them.","Sustained consumption of pool, queue, and executor capacity shared with scheduled work.","reprocess_behavior decides whether existing runs in the range are re-run.","Pause or stop it with airflow.backfill_pause or airflow.backfill_cancel."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to backfill.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"from_date","type":"string","required":true,"description":"First logical date in the range, ISO 8601, e.g. 2026-08-01T00:00:00Z.","validation":{"pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$","max_length":40}},{"name":"to_date","type":"string","required":true,"description":"Last logical date in the range, ISO 8601.","validation":{"pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$","max_length":40}},{"name":"reprocess_behavior","type":"string","required":false,"default":"none","description":"What to do about intervals that already have a run — none (the default) skips them, failed re-runs the failed ones, completed re-runs every finished one.","validation":{"enum":["none","failed","completed"]}},{"name":"max_active_runs","type":"integer","required":false,"default":3,"description":"How many backfill runs may be in flight at once. Keep it small so scheduled work still gets slots.","validation":{"min":1,"max":100}},{"name":"run_backwards","type":"string","required":false,"default":"false","description":"Process the range newest interval first.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Reprocess one week of failed runs, three at a time","args":{"dag_id":"daily_sales_etl","from_date":"2026-07-29T00:00:00Z","reprocess_behavior":"failed","to_date":"2026-08-05T00:00:00Z"}}],"search_terms":["backfill","rerun a date range","reprocess history","catch up missed runs"]},{"id":"airflow.backfill_pause","title":"Pause a backfill (PUT /api/v2/backfills/{backfill_id}/pause)","summary":"Pause a running backfill so it stops creating further runs. Runs already in flight finish. This is how to give scheduled work its pool slots back without losing the backfill's progress — resume it in the Airflow UI, or cancel it with airflow.backfill_cancel.","description":"Pause a running backfill so it stops creating further runs. Runs already in flight finish. This is how to give scheduled work its pool slots back without losing the backfill's progress — resume it in the Airflow UI, or cancel it with airflow.backfill_cancel.","kind":"script","risk":"medium","side_effects":["Stops the backfill creating new DAG runs.","Backfill runs already in flight continue to completion.","Reversible — the backfill keeps its progress and can be resumed."],"args":[{"name":"backfill_id","type":"integer","required":true,"description":"Backfill id, as reported by airflow.backfills.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Pause a backfill that is starving scheduled runs","args":{"backfill_id":7}}],"search_terms":["pause backfill","stop backfill temporarily","free up slots"]},{"id":"airflow.backfills","title":"List backfills (GET /api/v2/backfills)","summary":"List backfills for one DAG with their date range, reprocess behavior, max_active_runs, and whether each is running, paused, or completed. Read it before starting another backfill — an already-running one is a common source of a saturated pool.","description":"List backfills for one DAG with their date range, reprocess behavior, max_active_runs, and whether each is running, paused, or completed. Read it before starting another backfill — an already-running one is a common source of a saturated pool.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/backfills endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id whose backfills to list.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Backfills returned in this page.","validation":{"min":1,"max":100}},{"name":"order_by","type":"string","required":false,"default":"-id","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Backfills for one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["list backfills","is a backfill running","backfill status"]},{"id":"airflow.connections","title":"List connection inventory (GET /api/v2/connections)","summary":"List Airflow connections by id, type, host, port, schema, and login, plus whether each one carries a password and an extra document. Secrets never leave the runner: the password and the whole extra field — where service account JSON, tokens, and TLS keys live — are dropped before the result is returned, so this answers \"does this connection exist and where does it point\", never \"what is the credential\".","description":"List Airflow connections by id, type, host, port, schema, and login, plus whether each one carries a password and an extra document. Secrets never leave the runner: the password and the whole extra field — where service account JSON, tokens, and TLS keys live — are dropped before the result is returned, so this answers \"does this connection exist and where does it point\", never \"what is the credential\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/connections endpoint.","Read-only — never writes or mutates data.","Returns connection metadata only; passwords and extra fields are removed on the host."],"args":[{"name":"connection_id_pattern","type":"string","required":false,"default":"","description":"Substring the connection id must contain. Empty lists every connection.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Connections returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every connection and where it points","args":{}},{"title":"Warehouse connections","args":{"connection_id_pattern":"warehouse"}}],"search_terms":["list connections","which connection","connection host","conn_id"]},{"id":"airflow.dag","title":"GET /api/v2/dags/{dag_id}","summary":"Show one DAG's summary — paused state, schedule, owners, tags, next run, concurrency limits, and last parse time. Use when you already know the dag_id; airflow.dag_details adds the parsed DAG-level parameters.","description":"Show one DAG's summary — paused state, schedule, owners, tags, next run, concurrency limits, and last parse time. Use when you already know the dag_id; airflow.dag_details adds the parsed DAG-level parameters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Summary for one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag schedule","is the dag paused","next dag run"]},{"id":"airflow.dag_details","title":"GET /api/v2/dags/{dag_id}/details","summary":"Show one DAG's full parsed definition — the summary fields plus timetable, catchup, start and end dates, default arguments, doc_md, params, dataset or asset schedule, and the file it was parsed from. This is what to read before unpausing a DAG, because it says whether catchup will backfill.","description":"Show one DAG's full parsed definition — the summary fields plus timetable, catchup, start and end dates, default arguments, doc_md, params, dataset or asset schedule, and the file it was parsed from. This is what to read before unpausing a DAG, because it says whether catchup will backfill.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/details endpoint.","Read-only — never writes or mutates data.","Includes DAG-level default_args and params as the DAG author wrote them."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Full definition, including catchup","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag catchup","dag timetable","dag default args","dag params"]},{"id":"airflow.dag_pause","title":"Pause a DAG (PATCH /api/v2/dags/{dag_id})","summary":"Pause one DAG so the scheduler stops creating new runs for it. Runs already in flight keep going. This is the standard containment step for a DAG that is failing in a loop or hammering a downstream system, and airflow.dag_unpause reverses it exactly.","description":"Pause one DAG so the scheduler stops creating new runs for it. Runs already in flight keep going. This is the standard containment step for a DAG that is failing in a loop or hammering a downstream system, and airflow.dag_unpause reverses it exactly.","kind":"script","risk":"medium","side_effects":["Sets is_paused true for the DAG; the scheduler creates no further runs.","Runs and task instances already in flight continue to completion.","Fully reversible with airflow.dag_unpause."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to pause.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Pause a DAG that keeps failing","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["pause dag","stop scheduling","stop the dag"]},{"id":"airflow.dag_run","title":"GET /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}","summary":"Show one DAG run — state, run type, logical date, queued/start/end times, duration, the conf it was triggered with, and its note. Use after airflow.dag_runs narrows to the run you care about.","description":"Show one DAG run — state, run type, logical date, queued/start/end times, duration, the conf it was triggered with, and its note. Use after airflow.dag_runs narrows to the run you care about.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/dagRuns/{dag_run_id} endpoint.","Read-only — never writes or mutates data.","Returns the run conf exactly as the trigger supplied it."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id, e.g. scheduled__2026-08-05T00:00:00+00:00 or manual__2026-08-05T09:14:22.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}}],"examples":[{"title":"One scheduled run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["dag run detail","run conf","why is this run queued"]},{"id":"airflow.dag_run_clear","title":"Clear and re-run a DAG run (POST .../dagRuns/{dag_run_id}/clear)","summary":"Clear task instances in one DAG run and let the scheduler run them again. This is the standard \"retry last night's failure\" action, and the cleared tasks execute for real with all their side effects. Run airflow.dag_run_clear_preview first to see exactly what it will touch.","description":"Clear task instances in one DAG run and let the scheduler run them again. This is the standard \"retry last night's failure\" action, and the cleared tasks execute for real with all their side effects. Run airflow.dag_run_clear_preview first to see exactly what it will touch.","kind":"script","risk":"high","side_effects":["Resets the matching task instances and re-queues them for execution.","Cleared tasks run again with their real side effects, including writes and third-party calls.","Sets the DAG run back to a running state."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Clear only failed task instances (true, the default) or every task instance in the run. Clearing everything re-runs tasks that already succeeded.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Retry the failed tasks in a run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["clear dag run","retry failed tasks","rerun the run","restart the run"]},{"id":"airflow.dag_run_clear_preview","title":"Preview clearing a DAG run (POST .../dagRuns/{dag_run_id}/clear, dry run)","summary":"Show which task instances airflow.dag_run_clear would reset, without changing anything. Airflow's clear is a dry run by default, and this action fixes it that way: read the list, confirm the blast radius, then run the real clear.","description":"Show which task instances airflow.dag_run_clear would reset, without changing anything. Airflow's clear is a dry run by default, and this action fixes it that way: read the list, confirm the blast radius, then run the real clear.","kind":"script","risk":"low","side_effects":["One HTTP POST with dry_run fixed true; Airflow computes the affected task instances and changes nothing.","Read-only in effect — no task instance or run state is modified."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Consider only failed task instances (true, the default) or every task instance in the run.","validation":{"enum":["true","false"]}}],"examples":[{"title":"What a retry of the failed tasks would touch","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["what would clearing do","preview retry","dry run clear"]},{"id":"airflow.dag_run_delete","title":"Delete a DAG run (DELETE .../dagRuns/{dag_run_id})","summary":"Delete one DAG run and its task-instance records from the metadata database. Irreversible: the run's history, durations, and notes are gone, and the log files it left behind are orphaned. Use it to clear a run created with a wrong logical date or conf, not to hide a failure — airflow.dag_run_set_state retires a run and keeps the record.","description":"Delete one DAG run and its task-instance records from the metadata database. Irreversible: the run's history, durations, and notes are gone, and the log files it left behind are orphaned. Use it to clear a run created with a wrong logical date or conf, not to hide a failure — airflow.dag_run_set_state retires a run and keeps the record.","kind":"script","risk":"high","side_effects":["Permanently removes the DAG run and its task-instance rows from the metadata database.","Run history, durations, notes, and XCom entries for the run are lost.","Cannot be undone; the scheduler may recreate a scheduled run for the same interval."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id to delete.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}}],"examples":[{"title":"Remove a run triggered with the wrong conf","args":{"dag_id":"daily_sales_etl","dag_run_id":"manual__2026-08-05T09:14:22"}}],"search_terms":["delete dag run","remove a run","drop the run record"]},{"id":"airflow.dag_run_set_state","title":"Set a DAG run's state (PATCH .../dagRuns/{dag_run_id})","summary":"Set one DAG run to queued, success, or failed. Marking a run failed stops the scheduler from starting further tasks in it; marking it success closes it out without running the remaining tasks, which is how a stuck run is retired — and also how work gets silently skipped, so state the reason in the note. Setting it queued makes the scheduler re-examine the run.","description":"Set one DAG run to queued, success, or failed. Marking a run failed stops the scheduler from starting further tasks in it; marking it success closes it out without running the remaining tasks, which is how a stuck run is retired — and also how work gets silently skipped, so state the reason in the note. Setting it queued makes the scheduler re-examine the run.","kind":"script","risk":"high","side_effects":["Changes the run's state in the metadata database.","success or failed ends the run; remaining tasks are not executed.","queued causes the scheduler to re-evaluate and can start tasks again.","Downstream DAGs scheduled on this run's assets react to the new state."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"state","type":"string","required":true,"description":"New run state.","validation":{"enum":["queued","success","failed"]}}],"examples":[{"title":"Retire a run that will never finish","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"failed"}},{"title":"Send a run back to the scheduler","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"queued"}}],"search_terms":["mark run failed","mark run success","stuck dag run","force run to finish"]},{"id":"airflow.dag_run_trigger","title":"Trigger a DAG run (POST /api/v2/dags/{dag_id}/dagRuns)","summary":"Trigger a new run of one DAG. Every task in the DAG executes for real — writes to warehouses, calls to third parties, notifications — so this is a production change, not a test. Supply conf as a JSON object when the DAG reads dag_run.conf.","description":"Trigger a new run of one DAG. Every task in the DAG executes for real — writes to warehouses, calls to third parties, notifications — so this is a production change, not a test. Supply conf as a JSON object when the DAG reads dag_run.conf.","kind":"script","risk":"high","side_effects":["Creates a DAG run and executes the DAG's tasks with their real side effects.","Consumes pool, queue, and executor capacity shared with every other DAG.","Runs even when the DAG is paused."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to trigger.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"logical_date","type":"string","required":false,"default":"","description":"Logical date for the run as an ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z. Empty lets Airflow assign one, which is what an ad-hoc run wants.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Explicit run id. Empty lets Airflow generate a manual__ id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"conf","type":"string","required":false,"default":"","description":"Run configuration as a JSON object, e.g. {\"region\":\"eu\"}. Must parse as JSON; anything else fails before the request is sent.","validation":{"max_length":4096}},{"name":"note","type":"string","required":false,"default":"","description":"Free-text note recorded on the run, e.g. the incident it belongs to.","validation":{"max_length":1000}}],"examples":[{"title":"Run a DAG now","args":{"dag_id":"daily_sales_etl"}},{"title":"Run with configuration and a note","args":{"conf":"{\"region\":\"eu\"}","dag_id":"daily_sales_etl","note":"INC-4821 replay"}}],"search_terms":["trigger dag","run the dag now","manual dag run","rerun the pipeline"]},{"id":"airflow.dag_runs","title":"List DAG runs (GET /api/v2/dags/{dag_id}/dagRuns)","summary":"List DAG runs with their state, run type, queued/start/end times, duration, and who triggered them. Pass `dag_id: \"~\"` to search across every DAG at once — combined with `state: failed` that is the one call that answers \"what failed in the last hour\".","description":"List DAG runs with their state, run type, queued/start/end times, duration, and who triggered them. Pass `dag_id: \"~\"` to search across every DAG at once — combined with `state: failed` that is the one call that answers \"what failed in the last hour\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/dagRuns endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"~","description":"DAG id, or ~ (the default) to search runs across every DAG.","validation":{"pattern":"^([A-Za-z0-9._-]{1,250}|~)$","max_length":250}},{"name":"state","type":"string","required":false,"default":"","description":"Restrict to runs in this state. Empty lists every state.","validation":{"enum":["","queued","running","success","failed"]}},{"name":"run_type","type":"string","required":false,"default":"","description":"Restrict to runs of this type. Empty lists every type.","validation":{"enum":["","backfill","scheduled","manual","operator_triggered","asset_triggered","asset_materialization"]}},{"name":"start_date_gte","type":"string","required":false,"default":"","description":"Only runs that started at or after this ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Runs returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-run_after","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every failed run across the whole deployment","args":{"state":"failed"}},{"title":"Recent runs of one DAG","args":{"dag_id":"daily_sales_etl"}},{"title":"Runs still going right now","args":{"state":"running"}}],"search_terms":["failed runs","running dag runs","recent runs","what failed last night"]},{"id":"airflow.dag_stats","title":"Count DAG runs by state (GET /api/v2/dagStats)","summary":"Count each DAG's runs by state — queued, running, success, failed — in one call. The cheap triage read: it turns \"is anything wrong\" into a number per DAG without walking run lists.","description":"Count each DAG's runs by state — queued, running, success, failed — in one call. The cheap triage read: it turns \"is anything wrong\" into a number per DAG without walking run lists.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dagStats endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_ids","type":"string","required":false,"default":"","description":"Comma-separated dag_ids to count. Empty counts every DAG.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}}],"examples":[{"title":"Run counts for every DAG","args":{}},{"title":"Run counts for two DAGs","args":{"dag_ids":"daily_sales_etl,hourly_ingest"}}],"search_terms":["how many failed runs","queued runs count","dag run summary"]},{"id":"airflow.dag_tasks","title":"List a DAG's tasks (GET /api/v2/dags/{dag_id}/tasks)","summary":"List the tasks a DAG defines, with operator class, pool, queue, retries, trigger rule, and upstream/downstream ids. Read it to learn a DAG's shape before clearing a task or reasoning about which downstream work a failure blocks.","description":"List the tasks a DAG defines, with operator class, pool, queue, retries, trigger rule, and upstream/downstream ids. Read it to learn a DAG's shape before clearing a task or reasoning about which downstream work a failure blocks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/tasks endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Tasks in one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag tasks","task dependencies","which operator","task pool"]},{"id":"airflow.dag_unpause","title":"Unpause a DAG (PATCH /api/v2/dags/{dag_id})","summary":"Unpause one DAG so the scheduler resumes creating runs. Higher risk than the pause it reverses: a DAG with catchup enabled and an old start date creates one run per missed interval the moment it is unpaused, which can be hundreds of runs and can saturate every pool. Read airflow.dag_details first and check catchup and max_active_runs.","description":"Unpause one DAG so the scheduler resumes creating runs. Higher risk than the pause it reverses: a DAG with catchup enabled and an old start date creates one run per missed interval the moment it is unpaused, which can be hundreds of runs and can saturate every pool. Read airflow.dag_details first and check catchup and max_active_runs.","kind":"script","risk":"high","side_effects":["Sets is_paused false for the DAG; the scheduler resumes creating runs.","With catchup enabled, immediately schedules every interval missed while paused.","Consumes pool and executor slots shared with every other DAG."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to unpause.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Resume a DAG after the fix is deployed","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["unpause dag","resume dag","enable dag","turn the dag back on"]},{"id":"airflow.dag_warnings","title":"List DAG warnings (GET /api/v2/dagWarnings)","summary":"List non-fatal DAG warnings the scheduler recorded — a task referencing a pool that does not exist, an asset conflict, a value that varies between parses. These do not break parsing, so they are invisible until a task queues forever against a missing pool.","description":"List non-fatal DAG warnings the scheduler recorded — a task referencing a pool that does not exist, an asset conflict, a value that varies between parses. These do not break parsing, so they are invisible until a task queues forever against a missing pool.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dagWarnings endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"","description":"Restrict to one DAG. Empty lists warnings for every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Warnings returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"Every recorded DAG warning","args":{}}],"search_terms":["non-existent pool","dag warning","asset conflict"]},{"id":"airflow.dags","title":"List DAGs (GET /api/v2/dags)","summary":"List DAGs with their paused state, schedule, owners, tags, last parse time, and whether they currently have import errors. Filter by name pattern, tag, paused state, or the state of the most recent run — `last_dag_run_state: failed` is the fastest way to see everything that is broken right now.","description":"List DAGs with their paused state, schedule, owners, tags, last parse time, and whether they currently have import errors. Filter by name pattern, tag, paused state, or the state of the most recent run — `last_dag_run_state: failed` is the fastest way to see everything that is broken right now.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id_pattern","type":"string","required":false,"default":"","description":"Substring the dag_id must contain. Empty lists every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"tags","type":"string","required":false,"default":"","description":"Comma-separated DAG tags; a DAG matching any of them is included.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,250}$","max_length":250}},{"name":"paused","type":"string","required":false,"default":"","description":"Restrict to paused (true) or unpaused (false) DAGs. Empty lists both.","validation":{"enum":["","true","false"]}},{"name":"last_dag_run_state","type":"string","required":false,"default":"","description":"Restrict to DAGs whose most recent run is in this state.","validation":{"enum":["","queued","running","success","failed"]}},{"name":"exclude_stale","type":"string","required":false,"default":"true","description":"Hide DAGs whose file is no longer present (true, the default) or include them.","validation":{"enum":["true","false"]}},{"name":"limit","type":"integer","required":false,"default":50,"description":"DAGs returned in this page.","validation":{"min":1,"max":200}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset, for walking past the first page.","validation":{"min":0,"max":100000}},{"name":"order_by","type":"string","required":false,"default":"dag_id","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every DAG","args":{}},{"title":"DAGs whose last run failed","args":{"last_dag_run_state":"failed"}},{"title":"One team's DAGs","args":{"tags":"platform,ingest"}}],"search_terms":["list dags","paused dags","failing dags","dags by tag"]},{"id":"airflow.event_logs","title":"List Airflow event log entries (GET /api/v2/eventLogs)","summary":"List Airflow's own audit trail — who paused a DAG, triggered a run, cleared a task, or edited a variable, with the owner and timestamp. Read it to answer \"who changed this and when\" after an unexplained state change.","description":"List Airflow's own audit trail — who paused a DAG, triggered a run, cleared a task, or edited a variable, with the owner and timestamp. Read it to answer \"who changed this and when\" after an unexplained state change.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/eventLogs endpoint.","Read-only — never writes or mutates data.","Discloses which users acted on which DAGs."],"args":[{"name":"dag_id","type":"string","required":false,"default":"","description":"Restrict to events for one DAG. Empty lists every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"task_id","type":"string","required":false,"default":"","description":"Restrict to events for one task.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"event","type":"string","required":false,"default":"","description":"Restrict to one event name, e.g. trigger, clear, paused.","validation":{"pattern":"^[A-Za-z0-9._-]{0,64}$","max_length":64}},{"name":"after","type":"string","required":false,"default":"","description":"Only events at or after this ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Events returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-when","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Recent activity across the deployment","args":{}},{"title":"Who paused this DAG","args":{"dag_id":"daily_sales_etl","event":"paused"}}],"search_terms":["who paused the dag","who triggered this","airflow audit log","who cleared the task"]},{"id":"airflow.health","title":"GET /api/v2/monitor/health","summary":"Check Airflow control-plane health — whether the metadata database is reachable and when the scheduler, triggerer, and DAG processor last sent a heartbeat. Start here when DAGs stopped running: a scheduler reporting \"unhealthy\" explains an entire fleet of queued-but-never-started runs. Needs no credentials.","description":"Check Airflow control-plane health — whether the metadata database is reachable and when the scheduler, triggerer, and DAG processor last sent a heartbeat. Start here when DAGs stopped running: a scheduler reporting \"unhealthy\" explains an entire fleet of queued-but-never-started runs. Needs no credentials.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/monitor/health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check scheduler and triggerer health","args":{}}],"search_terms":["scheduler down","dags not running","triggerer heartbeat","airflow unhealthy"]},{"id":"airflow.import_errors","title":"List DAG import errors (GET /api/v2/importErrors)","summary":"List DAG files that failed to parse, with the filename, the timestamp, and the Python traceback. This is the answer to \"my DAG disappeared from the UI\" and to a deploy that silently stopped scheduling: a file with an import error contributes no DAGs at all.","description":"List DAG files that failed to parse, with the filename, the timestamp, and the Python traceback. This is the answer to \"my DAG disappeared from the UI\" and to a deploy that silently stopped scheduling: a file with an import error contributes no DAGs at all.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/importErrors endpoint.","Read-only — never writes or mutates data.","Returns the Python traceback recorded for each failing DAG file."],"args":[{"name":"filename_pattern","type":"string","required":false,"default":"","description":"Substring the DAG file path must contain. Empty lists every import error.","validation":{"pattern":"^[A-Za-z0-9._/-]{0,512}$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Import errors returned in this page.","validation":{"min":1,"max":100}},{"name":"order_by","type":"string","required":false,"default":"-timestamp","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every DAG file that fails to parse","args":{}}],"search_terms":["dag not showing up","broken dag","import error","dag parse failure"]},{"id":"airflow.jobs","title":"List Airflow jobs (GET /api/v2/jobs)","summary":"List Airflow's own scheduler, triggerer, and DAG-processor jobs with their state, hostname, executor class, and last heartbeat. Where airflow.health answers \"is the scheduler healthy\", this answers \"which hosts are running one and which one went quiet\" — the read for a multi-scheduler deployment.","description":"List Airflow's own scheduler, triggerer, and DAG-processor jobs with their state, hostname, executor class, and last heartbeat. Where airflow.health answers \"is the scheduler healthy\", this answers \"which hosts are running one and which one went quiet\" — the read for a multi-scheduler deployment.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/jobs endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"job_type","type":"string","required":false,"default":"","description":"Restrict to one job type, e.g. SchedulerJob, TriggererJob, DagProcessorJob. Empty lists every type.","validation":{"pattern":"^[A-Za-z]{0,64}$","max_length":64}},{"name":"is_alive","type":"string","required":false,"default":"","description":"Restrict to jobs whose heartbeat is current (true) or stale (false). Empty lists both.","validation":{"enum":["","true","false"]}},{"name":"hostname","type":"string","required":false,"default":"","description":"Restrict to jobs running on one host.","validation":{"pattern":"^[A-Za-z0-9._-]{0,253}$","max_length":253}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Jobs returned in this page.","validation":{"min":1,"max":500}},{"name":"order_by","type":"string","required":false,"default":"-latest_heartbeat","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every job, newest heartbeat first","args":{}},{"title":"Schedulers that stopped heartbeating","args":{"is_alive":"false","job_type":"SchedulerJob"}}],"search_terms":["scheduler hosts","triggerer job","stale heartbeat","which scheduler is alive"]},{"id":"airflow.pool_set_slots","title":"Set a pool's slot count (PATCH /api/v2/pools/{pool_name})","summary":"Set how many slots a pool has. This is the throttle: lower it to shed load from a database that is struggling, raise it when the bottleneck is gone. Bounded and reversible — the change applies to scheduling decisions from now on and never touches tasks already running.","description":"Set how many slots a pool has. This is the throttle: lower it to shed load from a database that is struggling, raise it when the bottleneck is gone. Bounded and reversible — the change applies to scheduling decisions from now on and never touches tasks already running.","kind":"script","risk":"medium","side_effects":["Changes the pool's total slots, so the scheduler admits more or fewer tasks.","Lowering slots leaves already-running tasks alone; they finish normally.","Lowering slots below current occupancy queues subsequent tasks until slots free up.","Reversible by setting the previous value again."],"args":[{"name":"pool_name","type":"string","required":true,"description":"Pool to change, as listed by airflow.pools.","validation":{"pattern":"^[A-Za-z0-9._-]{1,256}$","max_length":256}},{"name":"slots","type":"integer","required":true,"description":"New slot count. 0 stops the pool admitting any task; -1 makes it unlimited.","validation":{"min":-1,"max":100000}}],"examples":[{"title":"Halve a pool while the warehouse recovers","args":{"pool_name":"warehouse","slots":4}}],"search_terms":["pool slots","throttle airflow","reduce concurrency","increase parallelism"]},{"id":"airflow.pools","title":"List pools (GET /api/v2/pools)","summary":"List Airflow pools with total slots and how many are occupied, running, queued, scheduled, deferred, and open. A pool with zero open slots is the usual reason tasks sit queued while the scheduler looks healthy.","description":"List Airflow pools with total slots and how many are occupied, running, queued, scheduled, deferred, and open. A pool with zero open slots is the usual reason tasks sit queued while the scheduler looks healthy.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/pools endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"pool_name_pattern","type":"string","required":false,"default":"","description":"Substring the pool name must contain. Empty lists every pool.","validation":{"pattern":"^[A-Za-z0-9._-]{0,256}$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Pools returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every pool and its free slots","args":{}}],"search_terms":["pool slots","tasks stuck queued","pool full","concurrency limit"]},{"id":"airflow.providers","title":"List installed providers (GET /api/v2/providers)","summary":"List the Airflow provider packages installed on the API server with their versions and descriptions. Read it when an operator or a hook behaves differently than the docs say — a provider version mismatch across a fleet is a common cause.","description":"List the Airflow provider packages installed on the API server with their versions and descriptions. Read it when an operator or a hook behaves differently than the docs say — a provider version mismatch across a fleet is a common cause.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/providers endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Providers returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Installed providers and versions","args":{}}],"search_terms":["provider version","installed providers","apache-airflow-providers"]},{"id":"airflow.task_instance","title":"GET .../taskInstances/{task_id}","summary":"Show one task instance — state, try number against max_tries, start and end times, duration, hostname, pool, queue, executor, and the trigger it is deferred on. Read it before clearing a task, to see whether retries are already exhausted.","description":"Show one task instance — state, try number against max_tries, start and end times, duration, hostname, pool, queue, executor, and the trigger it is deferred on. Read it before clearing a task, to see whether retries are already exhausted.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow task-instance endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}}],"examples":[{"title":"One task instance","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_id":"load_warehouse"}},{"title":"One mapped task instance","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","map_index":3,"task_id":"load_partition"}}],"search_terms":["task instance detail","retries left","deferred task"]},{"id":"airflow.task_instance_set_state","title":"Set a task instance's state (PATCH .../taskInstances/{task_id})","summary":"Set one task instance to success, failed, or skipped without running it. Marking a stuck task success unblocks its downstream work — and asserts that the work happened when it did not, so use it only when you have confirmed the effect by other means. failed stops the branch; skipped passes it over.","description":"Set one task instance to success, failed, or skipped without running it. Marking a stuck task success unblocks its downstream work — and asserts that the work happened when it did not, so use it only when you have confirmed the effect by other means. failed stops the branch; skipped passes it over.","kind":"script","risk":"high","side_effects":["Changes the task instance's state in the metadata database without executing the task.","Downstream tasks proceed or stop according to the new state and their trigger rules.","With include_downstream, applies the same state to every downstream task.","Does not perform the work the task would have done."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"state","type":"string","required":true,"description":"New task-instance state.","validation":{"enum":["success","failed","skipped"]}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Apply the same state to every task downstream of this one.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Mark a task that was fixed by hand as done","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"success","task_id":"load_warehouse"}}],"search_terms":["mark task success","mark task failed","skip a task","unblock downstream tasks"]},{"id":"airflow.task_instances","title":"List task instances (GET .../dagRuns/{dag_run_id}/taskInstances)","summary":"List task instances with state, try number, duration, hostname, operator, pool, and queue. Pass `~` for dag_id and dag_run_id to search across every DAG and run: `state: failed` finds every failing task in the deployment, `state: queued` with a pool filter shows what a saturated pool is holding up.","description":"List task instances with state, try number, duration, hostname, operator, pool, and queue. Pass `~` for dag_id and dag_run_id to search across every DAG and run: `state: failed` finds every failing task in the deployment, `state: queued` with a pool filter shows what a saturated pool is holding up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow task-instance list endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"~","description":"DAG id, or ~ (the default) to search across every DAG.","validation":{"pattern":"^([A-Za-z0-9._-]{1,250}|~)$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"~","description":"Run id, or ~ (the default) to search across every run.","validation":{"pattern":"^([A-Za-z0-9._:+-]{1,250}|~)$","max_length":250}},{"name":"task_id","type":"string","required":false,"default":"","description":"Restrict to one task id. Empty lists every task.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"state","type":"string","required":false,"default":"","description":"Restrict to task instances in this state. Empty lists every state.","validation":{"enum":["","removed","scheduled","queued","running","success","restarting","failed","up_for_retry","up_for_reschedule","upstream_failed","skipped","deferred","awaiting_input"]}},{"name":"pool","type":"string","required":false,"default":"","description":"Restrict to task instances assigned to one pool.","validation":{"pattern":"^[A-Za-z0-9._-]{0,256}$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Task instances returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-start_date","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every failed task across the deployment","args":{"state":"failed"}},{"title":"Tasks in one run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}},{"title":"What a saturated pool is holding","args":{"pool":"warehouse","state":"queued"}}],"search_terms":["failed tasks","stuck tasks","queued task instances","which task failed","tasks up for retry"]},{"id":"airflow.task_instances_clear","title":"Clear and re-run task instances (POST /api/v2/dags/{dag_id}/clearTaskInstances)","summary":"Clear selected task instances of one DAG and let the scheduler run them again. Narrower than clearing a whole run: name the task ids, optionally one run, and optionally everything downstream. The cleared tasks execute for real. Run airflow.task_instances_clear_preview first.","description":"Clear selected task instances of one DAG and let the scheduler run them again. Narrower than clearing a whole run: name the task ids, optionally one run, and optionally everything downstream. The cleared tasks execute for real. Run airflow.task_instances_clear_preview first.","kind":"script","risk":"high","side_effects":["Resets the matching task instances and re-queues them for execution.","Cleared tasks run again with their real side effects, including writes and third-party calls.","Resets the DAG runs that own the cleared task instances.","With include_downstream, also re-runs every task that depends on the selected ones."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Restrict to one run. Empty clears matching tasks across every run of the DAG.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"task_ids","type":"string","required":false,"default":"","description":"Comma-separated task ids to clear. Empty clears every matching task.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Clear only failed task instances (true, the default) or every matching one. Clearing everything re-runs tasks that already succeeded.","validation":{"enum":["true","false"]}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Also clear every task downstream of the selected ones, so they re-run too.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Retry one failed task in one run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_ids":"load_warehouse"}}],"search_terms":["clear task","retry one task","rerun task instance","clear downstream tasks"]},{"id":"airflow.task_instances_clear_preview","title":"Preview clearing task instances (POST .../clearTaskInstances, dry run)","summary":"Show which task instances airflow.task_instances_clear would reset, without changing anything. Use it to check the reach of include_downstream before clearing a task in the middle of a DAG.","description":"Show which task instances airflow.task_instances_clear would reset, without changing anything. Use it to check the reach of include_downstream before clearing a task in the middle of a DAG.","kind":"script","risk":"low","side_effects":["One HTTP POST with dry_run fixed true; Airflow computes the affected task instances and changes nothing.","Read-only in effect — no task instance or run state is modified."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Restrict to one run. Empty considers every run of the DAG.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"task_ids","type":"string","required":false,"default":"","description":"Comma-separated task ids to clear. Empty considers every task.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Consider only failed task instances (true, the default) or every matching task instance.","validation":{"enum":["true","false"]}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Also consider every task downstream of the selected ones.","validation":{"enum":["true","false"]}}],"examples":[{"title":"What clearing one task and its downstream would touch","args":{"dag_id":"daily_sales_etl","include_downstream":"true","task_ids":"extract_orders"}}],"search_terms":["what would clearing this task do","preview downstream clear","dry run clear task"]},{"id":"airflow.task_log","title":"Get a task instance log (GET .../logs/{try_number})","summary":"Get the log for one attempt of one task instance, as plain text. This is the read that explains a failure: pick the try number from the task instance's try_number and read the traceback. Airflow's secrets masker hides connection and variable values it knows about; anything else the task printed is returned as written, which is why this needs an approval.","description":"Get the log for one attempt of one task instance, as plain text. This is the read that explains a failure: pick the try number from the task instance's try_number and read the traceback. Airflow's secrets masker hides connection and variable values it knows about; anything else the task printed is returned as written, which is why this needs an approval.","kind":"script","risk":"high","side_effects":["One read-only HTTP GET to the Airflow task-log endpoint.","Read-only — never writes or mutates data.","Returns whatever the task wrote to its log, subject to Airflow's own secrets masking."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"try_number","type":"integer","required":true,"description":"Attempt to read, starting at 1. The task instance's try_number is the latest.","validation":{"min":1,"max":1000}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}},{"name":"full_content","type":"string","required":false,"default":"true","description":"Return the whole log (true, the default) or only the metadata Airflow streams to the UI.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Log for the latest attempt","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_id":"load_warehouse","try_number":1}}],"search_terms":["task log","traceback","why did the task fail","stack trace"]},{"id":"airflow.variables","title":"List variable inventory (GET /api/v2/variables)","summary":"List Airflow variable keys with their description, whether they are encrypted, and how many bytes the value holds. Values never leave the runner — an Airflow variable routinely holds an API key or a DSN, and no redaction pattern can be trusted to catch every shape — so this answers \"does this variable exist and is it set\", never \"what is it\".","description":"List Airflow variable keys with their description, whether they are encrypted, and how many bytes the value holds. Values never leave the runner — an Airflow variable routinely holds an API key or a DSN, and no redaction pattern can be trusted to catch every shape — so this answers \"does this variable exist and is it set\", never \"what is it\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/variables endpoint.","Read-only — never writes or mutates data.","Returns variable keys and value length only; values are removed on the host."],"args":[{"name":"variable_key_pattern","type":"string","required":false,"default":"","description":"Substring the variable key must contain. Empty lists every variable.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Variables returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every variable key","args":{}}],"search_terms":["list variables","is the variable set","variable key"]},{"id":"airflow.version","title":"GET /api/v2/version","summary":"Show the Airflow version and git commit the API server is running. Use it to confirm which release a host is on before reading a version-specific field or filing an upgrade. Needs no credentials.","description":"Show the Airflow version and git commit the API server is running. Use it to confirm which release a host is on before reading a version-specific field or filing an upgrade. Needs no credentials.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/version endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Show the running Airflow version","args":{}}],"search_terms":["airflow version","which release"]}],"previous_versions":[{"version":"0.1.3","content_hash":"sha256:b149dbf5772e62d1c2e852ad087a6b41df3d4bc0ccd5fc2896e2190f7058dd0a","tarball_url":"https://registry.emisar.dev/v1/packs/airflow/0.1.3/b149dbf5772e62d1c2e852ad087a6b41df3d4bc0ccd5fc2896e2190f7058dd0a/pack.tar.gz","actions":[{"id":"airflow.asset_events","title":"List asset events (GET /api/v2/assets/events)","summary":"List asset update events with their timestamp and the DAG, task, and run that emitted each one. Pair with airflow.assets to answer \"when did this asset last update, and what produced it\" — the timeline behind a consumer DAG that has not triggered.","description":"List asset update events with their timestamp and the DAG, task, and run that emitted each one. Pair with airflow.assets to answer \"when did this asset last update, and what produced it\" — the timeline behind a consumer DAG that has not triggered.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/assets/events endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"asset_id","type":"integer","required":false,"default":0,"description":"Restrict to one asset by its numeric id, as reported by airflow.assets. 0 lists every asset.","validation":{"min":0,"max":9007199254740991}},{"name":"source_dag_id","type":"string","required":false,"default":"","description":"Restrict to events emitted by one DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Events returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-timestamp","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Most recent asset events","args":{}}],"search_terms":["asset event","when did the asset update","dataset event"]},{"id":"airflow.assets","title":"List assets (GET /api/v2/assets)","summary":"List the assets Airflow schedules on, with the tasks that produce them, the DAGs that consume them, and each asset's last event. In an asset-driven deployment a consumer DAG that never runs is usually waiting on a producer that stopped emitting — this read shows which one.","description":"List the assets Airflow schedules on, with the tasks that produce them, the DAGs that consume them, and each asset's last event. In an asset-driven deployment a consumer DAG that never runs is usually waiting on a producer that stopped emitting — this read shows which one.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/assets endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name_pattern","type":"string","required":false,"default":"","description":"Substring the asset name must contain. Empty lists every asset.","validation":{"pattern":"^[A-Za-z0-9._:/-]{0,250}$","max_length":250}},{"name":"dag_ids","type":"string","required":false,"default":"","description":"Comma-separated dag_ids; restricts to assets those DAGs produce or consume.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_active","type":"string","required":false,"default":"true","description":"Hide assets whose definition is gone (true, the default) or include them.","validation":{"enum":["true","false"]}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Assets returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"Every asset and its producers","args":{}}],"search_terms":["asset scheduling","data-aware scheduling","dataset","consumer dag not running"]},{"id":"airflow.backfill_cancel","title":"Cancel a backfill (PUT /api/v2/backfills/{backfill_id}/cancel)","summary":"Cancel a backfill. Its queued runs are dropped and running task instances are stopped, so a partially reprocessed date range is left partially reprocessed — which downstream consumers may read as complete. Prefer airflow.backfill_pause when the goal is only to free capacity.","description":"Cancel a backfill. Its queued runs are dropped and running task instances are stopped, so a partially reprocessed date range is left partially reprocessed — which downstream consumers may read as complete. Prefer airflow.backfill_pause when the goal is only to free capacity.","kind":"script","risk":"high","side_effects":["Stops the backfill and cancels its remaining runs.","Task instances still running are terminated mid-flight, which can leave partial writes.","The date range is left partly reprocessed; the backfill cannot be resumed."],"args":[{"name":"backfill_id","type":"integer","required":true,"description":"Backfill id, as reported by airflow.backfills.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Abandon a backfill started with the wrong range","args":{"backfill_id":7}}],"search_terms":["cancel backfill","stop backfill","kill backfill"]},{"id":"airflow.backfill_create","title":"Start a backfill (POST /api/v2/backfills)","summary":"Start a backfill of one DAG over a date range. Airflow creates one run per interval in the range and executes them for real, so a wide range is a large, sustained production load: every task writes what it normally writes and competes for the same pools as scheduled work. Bound it with max_active_runs and check airflow.backfills first.","description":"Start a backfill of one DAG over a date range. Airflow creates one run per interval in the range and executes them for real, so a wide range is a large, sustained production load: every task writes what it normally writes and competes for the same pools as scheduled work. Bound it with max_active_runs and check airflow.backfills first.","kind":"script","risk":"high","side_effects":["Creates one DAG run per interval in the range and executes every task in them.","Sustained consumption of pool, queue, and executor capacity shared with scheduled work.","reprocess_behavior decides whether existing runs in the range are re-run.","Pause or stop it with airflow.backfill_pause or airflow.backfill_cancel."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to backfill.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"from_date","type":"string","required":true,"description":"First logical date in the range, ISO 8601, e.g. 2026-08-01T00:00:00Z.","validation":{"pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$","max_length":40}},{"name":"to_date","type":"string","required":true,"description":"Last logical date in the range, ISO 8601.","validation":{"pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$","max_length":40}},{"name":"reprocess_behavior","type":"string","required":false,"default":"none","description":"What to do about intervals that already have a run — none (the default) skips them, failed re-runs the failed ones, completed re-runs every finished one.","validation":{"enum":["none","failed","completed"]}},{"name":"max_active_runs","type":"integer","required":false,"default":3,"description":"How many backfill runs may be in flight at once. Keep it small so scheduled work still gets slots.","validation":{"min":1,"max":100}},{"name":"run_backwards","type":"string","required":false,"default":"false","description":"Process the range newest interval first.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Reprocess one week of failed runs, three at a time","args":{"dag_id":"daily_sales_etl","from_date":"2026-07-29T00:00:00Z","reprocess_behavior":"failed","to_date":"2026-08-05T00:00:00Z"}}],"search_terms":["backfill","rerun a date range","reprocess history","catch up missed runs"]},{"id":"airflow.backfill_pause","title":"Pause a backfill (PUT /api/v2/backfills/{backfill_id}/pause)","summary":"Pause a running backfill so it stops creating further runs. Runs already in flight finish. This is how to give scheduled work its pool slots back without losing the backfill's progress — resume it in the Airflow UI, or cancel it with airflow.backfill_cancel.","description":"Pause a running backfill so it stops creating further runs. Runs already in flight finish. This is how to give scheduled work its pool slots back without losing the backfill's progress — resume it in the Airflow UI, or cancel it with airflow.backfill_cancel.","kind":"script","risk":"medium","side_effects":["Stops the backfill creating new DAG runs.","Backfill runs already in flight continue to completion.","Reversible — the backfill keeps its progress and can be resumed."],"args":[{"name":"backfill_id","type":"integer","required":true,"description":"Backfill id, as reported by airflow.backfills.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Pause a backfill that is starving scheduled runs","args":{"backfill_id":7}}],"search_terms":["pause backfill","stop backfill temporarily","free up slots"]},{"id":"airflow.backfills","title":"List backfills (GET /api/v2/backfills)","summary":"List backfills for one DAG with their date range, reprocess behavior, max_active_runs, and whether each is running, paused, or completed. Read it before starting another backfill — an already-running one is a common source of a saturated pool.","description":"List backfills for one DAG with their date range, reprocess behavior, max_active_runs, and whether each is running, paused, or completed. Read it before starting another backfill — an already-running one is a common source of a saturated pool.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/backfills endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id whose backfills to list.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Backfills returned in this page.","validation":{"min":1,"max":100}},{"name":"order_by","type":"string","required":false,"default":"-id","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Backfills for one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["list backfills","is a backfill running","backfill status"]},{"id":"airflow.connections","title":"List connection inventory (GET /api/v2/connections)","summary":"List Airflow connections by id, type, host, port, schema, and login, plus whether each one carries a password and an extra document. Secrets never leave the runner: the password and the whole extra field — where service account JSON, tokens, and TLS keys live — are dropped before the result is returned, so this answers \"does this connection exist and where does it point\", never \"what is the credential\".","description":"List Airflow connections by id, type, host, port, schema, and login, plus whether each one carries a password and an extra document. Secrets never leave the runner: the password and the whole extra field — where service account JSON, tokens, and TLS keys live — are dropped before the result is returned, so this answers \"does this connection exist and where does it point\", never \"what is the credential\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/connections endpoint.","Read-only — never writes or mutates data.","Returns connection metadata only; passwords and extra fields are removed on the host."],"args":[{"name":"connection_id_pattern","type":"string","required":false,"default":"","description":"Substring the connection id must contain. Empty lists every connection.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Connections returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every connection and where it points","args":{}},{"title":"Warehouse connections","args":{"connection_id_pattern":"warehouse"}}],"search_terms":["list connections","which connection","connection host","conn_id"]},{"id":"airflow.dag","title":"GET /api/v2/dags/{dag_id}","summary":"Show one DAG's summary — paused state, schedule, owners, tags, next run, concurrency limits, and last parse time. Use when you already know the dag_id; airflow.dag_details adds the parsed DAG-level parameters.","description":"Show one DAG's summary — paused state, schedule, owners, tags, next run, concurrency limits, and last parse time. Use when you already know the dag_id; airflow.dag_details adds the parsed DAG-level parameters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Summary for one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag schedule","is the dag paused","next dag run"]},{"id":"airflow.dag_details","title":"GET /api/v2/dags/{dag_id}/details","summary":"Show one DAG's full parsed definition — the summary fields plus timetable, catchup, start and end dates, default arguments, doc_md, params, dataset or asset schedule, and the file it was parsed from. This is what to read before unpausing a DAG, because it says whether catchup will backfill.","description":"Show one DAG's full parsed definition — the summary fields plus timetable, catchup, start and end dates, default arguments, doc_md, params, dataset or asset schedule, and the file it was parsed from. This is what to read before unpausing a DAG, because it says whether catchup will backfill.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/details endpoint.","Read-only — never writes or mutates data.","Includes DAG-level default_args and params as the DAG author wrote them."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Full definition, including catchup","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag catchup","dag timetable","dag default args","dag params"]},{"id":"airflow.dag_pause","title":"Pause a DAG (PATCH /api/v2/dags/{dag_id})","summary":"Pause one DAG so the scheduler stops creating new runs for it. Runs already in flight keep going. This is the standard containment step for a DAG that is failing in a loop or hammering a downstream system, and airflow.dag_unpause reverses it exactly.","description":"Pause one DAG so the scheduler stops creating new runs for it. Runs already in flight keep going. This is the standard containment step for a DAG that is failing in a loop or hammering a downstream system, and airflow.dag_unpause reverses it exactly.","kind":"script","risk":"medium","side_effects":["Sets is_paused true for the DAG; the scheduler creates no further runs.","Runs and task instances already in flight continue to completion.","Fully reversible with airflow.dag_unpause."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to pause.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Pause a DAG that keeps failing","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["pause dag","stop scheduling","stop the dag"]},{"id":"airflow.dag_run","title":"GET /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}","summary":"Show one DAG run — state, run type, logical date, queued/start/end times, duration, the conf it was triggered with, and its note. Use after airflow.dag_runs narrows to the run you care about.","description":"Show one DAG run — state, run type, logical date, queued/start/end times, duration, the conf it was triggered with, and its note. Use after airflow.dag_runs narrows to the run you care about.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/dagRuns/{dag_run_id} endpoint.","Read-only — never writes or mutates data.","Returns the run conf exactly as the trigger supplied it."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id, e.g. scheduled__2026-08-05T00:00:00+00:00 or manual__2026-08-05T09:14:22.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}}],"examples":[{"title":"One scheduled run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["dag run detail","run conf","why is this run queued"]},{"id":"airflow.dag_run_clear","title":"Clear and re-run a DAG run (POST .../dagRuns/{dag_run_id}/clear)","summary":"Clear task instances in one DAG run and let the scheduler run them again. This is the standard \"retry last night's failure\" action, and the cleared tasks execute for real with all their side effects. Run airflow.dag_run_clear_preview first to see exactly what it will touch.","description":"Clear task instances in one DAG run and let the scheduler run them again. This is the standard \"retry last night's failure\" action, and the cleared tasks execute for real with all their side effects. Run airflow.dag_run_clear_preview first to see exactly what it will touch.","kind":"script","risk":"high","side_effects":["Resets the matching task instances and re-queues them for execution.","Cleared tasks run again with their real side effects, including writes and third-party calls.","Sets the DAG run back to a running state."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Clear only failed task instances (true, the default) or every task instance in the run. Clearing everything re-runs tasks that already succeeded.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Retry the failed tasks in a run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["clear dag run","retry failed tasks","rerun the run","restart the run"]},{"id":"airflow.dag_run_clear_preview","title":"Preview clearing a DAG run (POST .../dagRuns/{dag_run_id}/clear, dry run)","summary":"Show which task instances airflow.dag_run_clear would reset, without changing anything. Airflow's clear is a dry run by default, and this action fixes it that way: read the list, confirm the blast radius, then run the real clear.","description":"Show which task instances airflow.dag_run_clear would reset, without changing anything. Airflow's clear is a dry run by default, and this action fixes it that way: read the list, confirm the blast radius, then run the real clear.","kind":"script","risk":"low","side_effects":["One HTTP POST with dry_run fixed true; Airflow computes the affected task instances and changes nothing.","Read-only in effect — no task instance or run state is modified."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Consider only failed task instances (true, the default) or every task instance in the run.","validation":{"enum":["true","false"]}}],"examples":[{"title":"What a retry of the failed tasks would touch","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["what would clearing do","preview retry","dry run clear"]},{"id":"airflow.dag_run_delete","title":"Delete a DAG run (DELETE .../dagRuns/{dag_run_id})","summary":"Delete one DAG run and its task-instance records from the metadata database. Irreversible: the run's history, durations, and notes are gone, and the log files it left behind are orphaned. Use it to clear a run created with a wrong logical date or conf, not to hide a failure — airflow.dag_run_set_state retires a run and keeps the record.","description":"Delete one DAG run and its task-instance records from the metadata database. Irreversible: the run's history, durations, and notes are gone, and the log files it left behind are orphaned. Use it to clear a run created with a wrong logical date or conf, not to hide a failure — airflow.dag_run_set_state retires a run and keeps the record.","kind":"script","risk":"high","side_effects":["Permanently removes the DAG run and its task-instance rows from the metadata database.","Run history, durations, notes, and XCom entries for the run are lost.","Cannot be undone; the scheduler may recreate a scheduled run for the same interval."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id to delete.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}}],"examples":[{"title":"Remove a run triggered with the wrong conf","args":{"dag_id":"daily_sales_etl","dag_run_id":"manual__2026-08-05T09:14:22"}}],"search_terms":["delete dag run","remove a run","drop the run record"]},{"id":"airflow.dag_run_set_state","title":"Set a DAG run's state (PATCH .../dagRuns/{dag_run_id})","summary":"Set one DAG run to queued, success, or failed. Marking a run failed stops the scheduler from starting further tasks in it; marking it success closes it out without running the remaining tasks, which is how a stuck run is retired — and also how work gets silently skipped, so state the reason in the note. Setting it queued makes the scheduler re-examine the run.","description":"Set one DAG run to queued, success, or failed. Marking a run failed stops the scheduler from starting further tasks in it; marking it success closes it out without running the remaining tasks, which is how a stuck run is retired — and also how work gets silently skipped, so state the reason in the note. Setting it queued makes the scheduler re-examine the run.","kind":"script","risk":"high","side_effects":["Changes the run's state in the metadata database.","success or failed ends the run; remaining tasks are not executed.","queued causes the scheduler to re-evaluate and can start tasks again.","Downstream DAGs scheduled on this run's assets react to the new state."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"state","type":"string","required":true,"description":"New run state.","validation":{"enum":["queued","success","failed"]}}],"examples":[{"title":"Retire a run that will never finish","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"failed"}},{"title":"Send a run back to the scheduler","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"queued"}}],"search_terms":["mark run failed","mark run success","stuck dag run","force run to finish"]},{"id":"airflow.dag_run_trigger","title":"Trigger a DAG run (POST /api/v2/dags/{dag_id}/dagRuns)","summary":"Trigger a new run of one DAG. Every task in the DAG executes for real — writes to warehouses, calls to third parties, notifications — so this is a production change, not a test. Supply conf as a JSON object when the DAG reads dag_run.conf.","description":"Trigger a new run of one DAG. Every task in the DAG executes for real — writes to warehouses, calls to third parties, notifications — so this is a production change, not a test. Supply conf as a JSON object when the DAG reads dag_run.conf.","kind":"script","risk":"high","side_effects":["Creates a DAG run and executes the DAG's tasks with their real side effects.","Consumes pool, queue, and executor capacity shared with every other DAG.","Runs even when the DAG is paused."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to trigger.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"logical_date","type":"string","required":false,"default":"","description":"Logical date for the run as an ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z. Empty lets Airflow assign one, which is what an ad-hoc run wants.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Explicit run id. Empty lets Airflow generate a manual__ id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"conf","type":"string","required":false,"default":"","description":"Run configuration as a JSON object, e.g. {\"region\":\"eu\"}. Must parse as JSON; anything else fails before the request is sent.","validation":{"max_length":4096}},{"name":"note","type":"string","required":false,"default":"","description":"Free-text note recorded on the run, e.g. the incident it belongs to.","validation":{"max_length":1000}}],"examples":[{"title":"Run a DAG now","args":{"dag_id":"daily_sales_etl"}},{"title":"Run with configuration and a note","args":{"conf":"{\"region\":\"eu\"}","dag_id":"daily_sales_etl","note":"INC-4821 replay"}}],"search_terms":["trigger dag","run the dag now","manual dag run","rerun the pipeline"]},{"id":"airflow.dag_runs","title":"List DAG runs (GET /api/v2/dags/{dag_id}/dagRuns)","summary":"List DAG runs with their state, run type, queued/start/end times, duration, and who triggered them. Pass `dag_id: \"~\"` to search across every DAG at once — combined with `state: failed` that is the one call that answers \"what failed in the last hour\".","description":"List DAG runs with their state, run type, queued/start/end times, duration, and who triggered them. Pass `dag_id: \"~\"` to search across every DAG at once — combined with `state: failed` that is the one call that answers \"what failed in the last hour\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/dagRuns endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"~","description":"DAG id, or ~ (the default) to search runs across every DAG.","validation":{"pattern":"^([A-Za-z0-9._-]{1,250}|~)$","max_length":250}},{"name":"state","type":"string","required":false,"default":"","description":"Restrict to runs in this state. Empty lists every state.","validation":{"enum":["","queued","running","success","failed"]}},{"name":"run_type","type":"string","required":false,"default":"","description":"Restrict to runs of this type. Empty lists every type.","validation":{"enum":["","backfill","scheduled","manual","operator_triggered","asset_triggered","asset_materialization"]}},{"name":"start_date_gte","type":"string","required":false,"default":"","description":"Only runs that started at or after this ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Runs returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-run_after","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every failed run across the whole deployment","args":{"state":"failed"}},{"title":"Recent runs of one DAG","args":{"dag_id":"daily_sales_etl"}},{"title":"Runs still going right now","args":{"state":"running"}}],"search_terms":["failed runs","running dag runs","recent runs","what failed last night"]},{"id":"airflow.dag_stats","title":"Count DAG runs by state (GET /api/v2/dagStats)","summary":"Count each DAG's runs by state — queued, running, success, failed — in one call. The cheap triage read: it turns \"is anything wrong\" into a number per DAG without walking run lists.","description":"Count each DAG's runs by state — queued, running, success, failed — in one call. The cheap triage read: it turns \"is anything wrong\" into a number per DAG without walking run lists.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dagStats endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_ids","type":"string","required":false,"default":"","description":"Comma-separated dag_ids to count. Empty counts every DAG.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}}],"examples":[{"title":"Run counts for every DAG","args":{}},{"title":"Run counts for two DAGs","args":{"dag_ids":"daily_sales_etl,hourly_ingest"}}],"search_terms":["how many failed runs","queued runs count","dag run summary"]},{"id":"airflow.dag_tasks","title":"List a DAG's tasks (GET /api/v2/dags/{dag_id}/tasks)","summary":"List the tasks a DAG defines, with operator class, pool, queue, retries, trigger rule, and upstream/downstream ids. Read it to learn a DAG's shape before clearing a task or reasoning about which downstream work a failure blocks.","description":"List the tasks a DAG defines, with operator class, pool, queue, retries, trigger rule, and upstream/downstream ids. Read it to learn a DAG's shape before clearing a task or reasoning about which downstream work a failure blocks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/tasks endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Tasks in one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag tasks","task dependencies","which operator","task pool"]},{"id":"airflow.dag_unpause","title":"Unpause a DAG (PATCH /api/v2/dags/{dag_id})","summary":"Unpause one DAG so the scheduler resumes creating runs. Higher risk than the pause it reverses: a DAG with catchup enabled and an old start date creates one run per missed interval the moment it is unpaused, which can be hundreds of runs and can saturate every pool. Read airflow.dag_details first and check catchup and max_active_runs.","description":"Unpause one DAG so the scheduler resumes creating runs. Higher risk than the pause it reverses: a DAG with catchup enabled and an old start date creates one run per missed interval the moment it is unpaused, which can be hundreds of runs and can saturate every pool. Read airflow.dag_details first and check catchup and max_active_runs.","kind":"script","risk":"high","side_effects":["Sets is_paused false for the DAG; the scheduler resumes creating runs.","With catchup enabled, immediately schedules every interval missed while paused.","Consumes pool and executor slots shared with every other DAG."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to unpause.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Resume a DAG after the fix is deployed","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["unpause dag","resume dag","enable dag","turn the dag back on"]},{"id":"airflow.dag_warnings","title":"List DAG warnings (GET /api/v2/dagWarnings)","summary":"List non-fatal DAG warnings the scheduler recorded — a task referencing a pool that does not exist, an asset conflict, a value that varies between parses. These do not break parsing, so they are invisible until a task queues forever against a missing pool.","description":"List non-fatal DAG warnings the scheduler recorded — a task referencing a pool that does not exist, an asset conflict, a value that varies between parses. These do not break parsing, so they are invisible until a task queues forever against a missing pool.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dagWarnings endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"","description":"Restrict to one DAG. Empty lists warnings for every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Warnings returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"Every recorded DAG warning","args":{}}],"search_terms":["non-existent pool","dag warning","asset conflict"]},{"id":"airflow.dags","title":"List DAGs (GET /api/v2/dags)","summary":"List DAGs with their paused state, schedule, owners, tags, last parse time, and whether they currently have import errors. Filter by name pattern, tag, paused state, or the state of the most recent run — `last_dag_run_state: failed` is the fastest way to see everything that is broken right now.","description":"List DAGs with their paused state, schedule, owners, tags, last parse time, and whether they currently have import errors. Filter by name pattern, tag, paused state, or the state of the most recent run — `last_dag_run_state: failed` is the fastest way to see everything that is broken right now.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id_pattern","type":"string","required":false,"default":"","description":"Substring the dag_id must contain. Empty lists every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"tags","type":"string","required":false,"default":"","description":"Comma-separated DAG tags; a DAG matching any of them is included.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,250}$","max_length":250}},{"name":"paused","type":"string","required":false,"default":"","description":"Restrict to paused (true) or unpaused (false) DAGs. Empty lists both.","validation":{"enum":["","true","false"]}},{"name":"last_dag_run_state","type":"string","required":false,"default":"","description":"Restrict to DAGs whose most recent run is in this state.","validation":{"enum":["","queued","running","success","failed"]}},{"name":"exclude_stale","type":"string","required":false,"default":"true","description":"Hide DAGs whose file is no longer present (true, the default) or include them.","validation":{"enum":["true","false"]}},{"name":"limit","type":"integer","required":false,"default":50,"description":"DAGs returned in this page.","validation":{"min":1,"max":200}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset, for walking past the first page.","validation":{"min":0,"max":100000}},{"name":"order_by","type":"string","required":false,"default":"dag_id","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every DAG","args":{}},{"title":"DAGs whose last run failed","args":{"last_dag_run_state":"failed"}},{"title":"One team's DAGs","args":{"tags":"platform,ingest"}}],"search_terms":["list dags","paused dags","failing dags","dags by tag"]},{"id":"airflow.event_logs","title":"List Airflow event log entries (GET /api/v2/eventLogs)","summary":"List Airflow's own audit trail — who paused a DAG, triggered a run, cleared a task, or edited a variable, with the owner and timestamp. Read it to answer \"who changed this and when\" after an unexplained state change.","description":"List Airflow's own audit trail — who paused a DAG, triggered a run, cleared a task, or edited a variable, with the owner and timestamp. Read it to answer \"who changed this and when\" after an unexplained state change.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/eventLogs endpoint.","Read-only — never writes or mutates data.","Discloses which users acted on which DAGs."],"args":[{"name":"dag_id","type":"string","required":false,"default":"","description":"Restrict to events for one DAG. Empty lists every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"task_id","type":"string","required":false,"default":"","description":"Restrict to events for one task.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"event","type":"string","required":false,"default":"","description":"Restrict to one event name, e.g. trigger, clear, paused.","validation":{"pattern":"^[A-Za-z0-9._-]{0,64}$","max_length":64}},{"name":"after","type":"string","required":false,"default":"","description":"Only events at or after this ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Events returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-when","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Recent activity across the deployment","args":{}},{"title":"Who paused this DAG","args":{"dag_id":"daily_sales_etl","event":"paused"}}],"search_terms":["who paused the dag","who triggered this","airflow audit log","who cleared the task"]},{"id":"airflow.health","title":"GET /api/v2/monitor/health","summary":"Check Airflow control-plane health — whether the metadata database is reachable and when the scheduler, triggerer, and DAG processor last sent a heartbeat. Start here when DAGs stopped running: a scheduler reporting \"unhealthy\" explains an entire fleet of queued-but-never-started runs. Needs no credentials.","description":"Check Airflow control-plane health — whether the metadata database is reachable and when the scheduler, triggerer, and DAG processor last sent a heartbeat. Start here when DAGs stopped running: a scheduler reporting \"unhealthy\" explains an entire fleet of queued-but-never-started runs. Needs no credentials.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/monitor/health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check scheduler and triggerer health","args":{}}],"search_terms":["scheduler down","dags not running","triggerer heartbeat","airflow unhealthy"]},{"id":"airflow.import_errors","title":"List DAG import errors (GET /api/v2/importErrors)","summary":"List DAG files that failed to parse, with the filename, the timestamp, and the Python traceback. This is the answer to \"my DAG disappeared from the UI\" and to a deploy that silently stopped scheduling: a file with an import error contributes no DAGs at all.","description":"List DAG files that failed to parse, with the filename, the timestamp, and the Python traceback. This is the answer to \"my DAG disappeared from the UI\" and to a deploy that silently stopped scheduling: a file with an import error contributes no DAGs at all.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/importErrors endpoint.","Read-only — never writes or mutates data.","Returns the Python traceback recorded for each failing DAG file."],"args":[{"name":"filename_pattern","type":"string","required":false,"default":"","description":"Substring the DAG file path must contain. Empty lists every import error.","validation":{"pattern":"^[A-Za-z0-9._/-]{0,512}$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Import errors returned in this page.","validation":{"min":1,"max":100}},{"name":"order_by","type":"string","required":false,"default":"-timestamp","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every DAG file that fails to parse","args":{}}],"search_terms":["dag not showing up","broken dag","import error","dag parse failure"]},{"id":"airflow.jobs","title":"List Airflow jobs (GET /api/v2/jobs)","summary":"List Airflow's own scheduler, triggerer, and DAG-processor jobs with their state, hostname, executor class, and last heartbeat. Where airflow.health answers \"is the scheduler healthy\", this answers \"which hosts are running one and which one went quiet\" — the read for a multi-scheduler deployment.","description":"List Airflow's own scheduler, triggerer, and DAG-processor jobs with their state, hostname, executor class, and last heartbeat. Where airflow.health answers \"is the scheduler healthy\", this answers \"which hosts are running one and which one went quiet\" — the read for a multi-scheduler deployment.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/jobs endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"job_type","type":"string","required":false,"default":"","description":"Restrict to one job type, e.g. SchedulerJob, TriggererJob, DagProcessorJob. Empty lists every type.","validation":{"pattern":"^[A-Za-z]{0,64}$","max_length":64}},{"name":"is_alive","type":"string","required":false,"default":"","description":"Restrict to jobs whose heartbeat is current (true) or stale (false). Empty lists both.","validation":{"enum":["","true","false"]}},{"name":"hostname","type":"string","required":false,"default":"","description":"Restrict to jobs running on one host.","validation":{"pattern":"^[A-Za-z0-9._-]{0,253}$","max_length":253}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Jobs returned in this page.","validation":{"min":1,"max":500}},{"name":"order_by","type":"string","required":false,"default":"-latest_heartbeat","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every job, newest heartbeat first","args":{}},{"title":"Schedulers that stopped heartbeating","args":{"is_alive":"false","job_type":"SchedulerJob"}}],"search_terms":["scheduler hosts","triggerer job","stale heartbeat","which scheduler is alive"]},{"id":"airflow.pool_set_slots","title":"Set a pool's slot count (PATCH /api/v2/pools/{pool_name})","summary":"Set how many slots a pool has. This is the throttle: lower it to shed load from a database that is struggling, raise it when the bottleneck is gone. Bounded and reversible — the change applies to scheduling decisions from now on and never touches tasks already running.","description":"Set how many slots a pool has. This is the throttle: lower it to shed load from a database that is struggling, raise it when the bottleneck is gone. Bounded and reversible — the change applies to scheduling decisions from now on and never touches tasks already running.","kind":"script","risk":"medium","side_effects":["Changes the pool's total slots, so the scheduler admits more or fewer tasks.","Lowering slots leaves already-running tasks alone; they finish normally.","Lowering slots below current occupancy queues subsequent tasks until slots free up.","Reversible by setting the previous value again."],"args":[{"name":"pool_name","type":"string","required":true,"description":"Pool to change, as listed by airflow.pools.","validation":{"pattern":"^[A-Za-z0-9._-]{1,256}$","max_length":256}},{"name":"slots","type":"integer","required":true,"description":"New slot count. 0 stops the pool admitting any task; -1 makes it unlimited.","validation":{"min":-1,"max":100000}}],"examples":[{"title":"Halve a pool while the warehouse recovers","args":{"pool_name":"warehouse","slots":4}}],"search_terms":["pool slots","throttle airflow","reduce concurrency","increase parallelism"]},{"id":"airflow.pools","title":"List pools (GET /api/v2/pools)","summary":"List Airflow pools with total slots and how many are occupied, running, queued, scheduled, deferred, and open. A pool with zero open slots is the usual reason tasks sit queued while the scheduler looks healthy.","description":"List Airflow pools with total slots and how many are occupied, running, queued, scheduled, deferred, and open. A pool with zero open slots is the usual reason tasks sit queued while the scheduler looks healthy.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/pools endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"pool_name_pattern","type":"string","required":false,"default":"","description":"Substring the pool name must contain. Empty lists every pool.","validation":{"pattern":"^[A-Za-z0-9._-]{0,256}$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Pools returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every pool and its free slots","args":{}}],"search_terms":["pool slots","tasks stuck queued","pool full","concurrency limit"]},{"id":"airflow.providers","title":"List installed providers (GET /api/v2/providers)","summary":"List the Airflow provider packages installed on the API server with their versions and descriptions. Read it when an operator or a hook behaves differently than the docs say — a provider version mismatch across a fleet is a common cause.","description":"List the Airflow provider packages installed on the API server with their versions and descriptions. Read it when an operator or a hook behaves differently than the docs say — a provider version mismatch across a fleet is a common cause.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/providers endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Providers returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Installed providers and versions","args":{}}],"search_terms":["provider version","installed providers","apache-airflow-providers"]},{"id":"airflow.task_instance","title":"GET .../taskInstances/{task_id}","summary":"Show one task instance — state, try number against max_tries, start and end times, duration, hostname, pool, queue, executor, and the trigger it is deferred on. Read it before clearing a task, to see whether retries are already exhausted.","description":"Show one task instance — state, try number against max_tries, start and end times, duration, hostname, pool, queue, executor, and the trigger it is deferred on. Read it before clearing a task, to see whether retries are already exhausted.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow task-instance endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}}],"examples":[{"title":"One task instance","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_id":"load_warehouse"}},{"title":"One mapped task instance","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","map_index":3,"task_id":"load_partition"}}],"search_terms":["task instance detail","retries left","deferred task"]},{"id":"airflow.task_instance_set_state","title":"Set a task instance's state (PATCH .../taskInstances/{task_id})","summary":"Set one task instance to success, failed, or skipped without running it. Marking a stuck task success unblocks its downstream work — and asserts that the work happened when it did not, so use it only when you have confirmed the effect by other means. failed stops the branch; skipped passes it over.","description":"Set one task instance to success, failed, or skipped without running it. Marking a stuck task success unblocks its downstream work — and asserts that the work happened when it did not, so use it only when you have confirmed the effect by other means. failed stops the branch; skipped passes it over.","kind":"script","risk":"high","side_effects":["Changes the task instance's state in the metadata database without executing the task.","Downstream tasks proceed or stop according to the new state and their trigger rules.","With include_downstream, applies the same state to every downstream task.","Does not perform the work the task would have done."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"state","type":"string","required":true,"description":"New task-instance state.","validation":{"enum":["success","failed","skipped"]}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Apply the same state to every task downstream of this one.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Mark a task that was fixed by hand as done","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"success","task_id":"load_warehouse"}}],"search_terms":["mark task success","mark task failed","skip a task","unblock downstream tasks"]},{"id":"airflow.task_instances","title":"List task instances (GET .../dagRuns/{dag_run_id}/taskInstances)","summary":"List task instances with state, try number, duration, hostname, operator, pool, and queue. Pass `~` for dag_id and dag_run_id to search across every DAG and run: `state: failed` finds every failing task in the deployment, `state: queued` with a pool filter shows what a saturated pool is holding up.","description":"List task instances with state, try number, duration, hostname, operator, pool, and queue. Pass `~` for dag_id and dag_run_id to search across every DAG and run: `state: failed` finds every failing task in the deployment, `state: queued` with a pool filter shows what a saturated pool is holding up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow task-instance list endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"~","description":"DAG id, or ~ (the default) to search across every DAG.","validation":{"pattern":"^([A-Za-z0-9._-]{1,250}|~)$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"~","description":"Run id, or ~ (the default) to search across every run.","validation":{"pattern":"^([A-Za-z0-9._:+-]{1,250}|~)$","max_length":250}},{"name":"task_id","type":"string","required":false,"default":"","description":"Restrict to one task id. Empty lists every task.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"state","type":"string","required":false,"default":"","description":"Restrict to task instances in this state. Empty lists every state.","validation":{"enum":["","removed","scheduled","queued","running","success","restarting","failed","up_for_retry","up_for_reschedule","upstream_failed","skipped","deferred","awaiting_input"]}},{"name":"pool","type":"string","required":false,"default":"","description":"Restrict to task instances assigned to one pool.","validation":{"pattern":"^[A-Za-z0-9._-]{0,256}$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Task instances returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-start_date","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every failed task across the deployment","args":{"state":"failed"}},{"title":"Tasks in one run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}},{"title":"What a saturated pool is holding","args":{"pool":"warehouse","state":"queued"}}],"search_terms":["failed tasks","stuck tasks","queued task instances","which task failed","tasks up for retry"]},{"id":"airflow.task_instances_clear","title":"Clear and re-run task instances (POST /api/v2/dags/{dag_id}/clearTaskInstances)","summary":"Clear selected task instances of one DAG and let the scheduler run them again. Narrower than clearing a whole run: name the task ids, optionally one run, and optionally everything downstream. The cleared tasks execute for real. Run airflow.task_instances_clear_preview first.","description":"Clear selected task instances of one DAG and let the scheduler run them again. Narrower than clearing a whole run: name the task ids, optionally one run, and optionally everything downstream. The cleared tasks execute for real. Run airflow.task_instances_clear_preview first.","kind":"script","risk":"high","side_effects":["Resets the matching task instances and re-queues them for execution.","Cleared tasks run again with their real side effects, including writes and third-party calls.","Resets the DAG runs that own the cleared task instances.","With include_downstream, also re-runs every task that depends on the selected ones."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Restrict to one run. Empty clears matching tasks across every run of the DAG.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"task_ids","type":"string","required":false,"default":"","description":"Comma-separated task ids to clear. Empty clears every matching task.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Clear only failed task instances (true, the default) or every matching one. Clearing everything re-runs tasks that already succeeded.","validation":{"enum":["true","false"]}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Also clear every task downstream of the selected ones, so they re-run too.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Retry one failed task in one run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_ids":"load_warehouse"}}],"search_terms":["clear task","retry one task","rerun task instance","clear downstream tasks"]},{"id":"airflow.task_instances_clear_preview","title":"Preview clearing task instances (POST .../clearTaskInstances, dry run)","summary":"Show which task instances airflow.task_instances_clear would reset, without changing anything. Use it to check the reach of include_downstream before clearing a task in the middle of a DAG.","description":"Show which task instances airflow.task_instances_clear would reset, without changing anything. Use it to check the reach of include_downstream before clearing a task in the middle of a DAG.","kind":"script","risk":"low","side_effects":["One HTTP POST with dry_run fixed true; Airflow computes the affected task instances and changes nothing.","Read-only in effect — no task instance or run state is modified."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Restrict to one run. Empty considers every run of the DAG.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"task_ids","type":"string","required":false,"default":"","description":"Comma-separated task ids to clear. Empty considers every task.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Consider only failed task instances (true, the default) or every matching task instance.","validation":{"enum":["true","false"]}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Also consider every task downstream of the selected ones.","validation":{"enum":["true","false"]}}],"examples":[{"title":"What clearing one task and its downstream would touch","args":{"dag_id":"daily_sales_etl","include_downstream":"true","task_ids":"extract_orders"}}],"search_terms":["what would clearing this task do","preview downstream clear","dry run clear task"]},{"id":"airflow.task_log","title":"Get a task instance log (GET .../logs/{try_number})","summary":"Get the log for one attempt of one task instance, as plain text. This is the read that explains a failure: pick the try number from the task instance's try_number and read the traceback. Airflow's secrets masker hides connection and variable values it knows about; anything else the task printed is returned as written, which is why this needs an approval.","description":"Get the log for one attempt of one task instance, as plain text. This is the read that explains a failure: pick the try number from the task instance's try_number and read the traceback. Airflow's secrets masker hides connection and variable values it knows about; anything else the task printed is returned as written, which is why this needs an approval.","kind":"script","risk":"high","side_effects":["One read-only HTTP GET to the Airflow task-log endpoint.","Read-only — never writes or mutates data.","Returns whatever the task wrote to its log, subject to Airflow's own secrets masking."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"try_number","type":"integer","required":true,"description":"Attempt to read, starting at 1. The task instance's try_number is the latest.","validation":{"min":1,"max":1000}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}},{"name":"full_content","type":"string","required":false,"default":"true","description":"Return the whole log (true, the default) or only the metadata Airflow streams to the UI.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Log for the latest attempt","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_id":"load_warehouse","try_number":1}}],"search_terms":["task log","traceback","why did the task fail","stack trace"]},{"id":"airflow.variables","title":"List variable inventory (GET /api/v2/variables)","summary":"List Airflow variable keys with their description, whether they are encrypted, and how many bytes the value holds. Values never leave the runner — an Airflow variable routinely holds an API key or a DSN, and no redaction pattern can be trusted to catch every shape — so this answers \"does this variable exist and is it set\", never \"what is it\".","description":"List Airflow variable keys with their description, whether they are encrypted, and how many bytes the value holds. Values never leave the runner — an Airflow variable routinely holds an API key or a DSN, and no redaction pattern can be trusted to catch every shape — so this answers \"does this variable exist and is it set\", never \"what is it\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/variables endpoint.","Read-only — never writes or mutates data.","Returns variable keys and value length only; values are removed on the host."],"args":[{"name":"variable_key_pattern","type":"string","required":false,"default":"","description":"Substring the variable key must contain. Empty lists every variable.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Variables returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every variable key","args":{}}],"search_terms":["list variables","is the variable set","variable key"]},{"id":"airflow.version","title":"GET /api/v2/version","summary":"Show the Airflow version and git commit the API server is running. Use it to confirm which release a host is on before reading a version-specific field or filing an upgrade. Needs no credentials.","description":"Show the Airflow version and git commit the API server is running. Use it to confirm which release a host is on before reading a version-specific field or filing an upgrade. Needs no credentials.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/version endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Show the running Airflow version","args":{}}],"search_terms":["airflow version","which release"]}]},{"version":"0.1.1","content_hash":"sha256:a4cb4365b5e5d9c780ac8b8e54471ea982082f1d50f9d5022ef8f2078847a051","tarball_url":"https://registry.emisar.dev/v1/packs/airflow/0.1.1/a4cb4365b5e5d9c780ac8b8e54471ea982082f1d50f9d5022ef8f2078847a051/pack.tar.gz","actions":[{"id":"airflow.asset_events","title":"List asset events (GET /api/v2/assets/events)","summary":"List asset update events with their timestamp and the DAG, task, and run that emitted each one. Pair with airflow.assets to answer \"when did this asset last update, and what produced it\" — the timeline behind a consumer DAG that has not triggered.","description":"List asset update events with their timestamp and the DAG, task, and run that emitted each one. Pair with airflow.assets to answer \"when did this asset last update, and what produced it\" — the timeline behind a consumer DAG that has not triggered.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/assets/events endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"asset_id","type":"integer","required":false,"default":0,"description":"Restrict to one asset by its numeric id, as reported by airflow.assets. 0 lists every asset.","validation":{"min":0,"max":9007199254740991}},{"name":"source_dag_id","type":"string","required":false,"default":"","description":"Restrict to events emitted by one DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Events returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-timestamp","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Most recent asset events","args":{}}],"search_terms":["asset event","when did the asset update","dataset event"]},{"id":"airflow.assets","title":"List assets (GET /api/v2/assets)","summary":"List the assets Airflow schedules on, with the tasks that produce them, the DAGs that consume them, and each asset's last event. In an asset-driven deployment a consumer DAG that never runs is usually waiting on a producer that stopped emitting — this read shows which one.","description":"List the assets Airflow schedules on, with the tasks that produce them, the DAGs that consume them, and each asset's last event. In an asset-driven deployment a consumer DAG that never runs is usually waiting on a producer that stopped emitting — this read shows which one.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/assets endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name_pattern","type":"string","required":false,"default":"","description":"Substring the asset name must contain. Empty lists every asset.","validation":{"pattern":"^[A-Za-z0-9._:/-]{0,250}$","max_length":250}},{"name":"dag_ids","type":"string","required":false,"default":"","description":"Comma-separated dag_ids; restricts to assets those DAGs produce or consume.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_active","type":"string","required":false,"default":"true","description":"Hide assets whose definition is gone (true, the default) or include them.","validation":{"enum":["true","false"]}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Assets returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"Every asset and its producers","args":{}}],"search_terms":["asset scheduling","data-aware scheduling","dataset","consumer dag not running"]},{"id":"airflow.backfill_cancel","title":"Cancel a backfill (PUT /api/v2/backfills/{backfill_id}/cancel)","summary":"Cancel a backfill. Its queued runs are dropped and running task instances are stopped, so a partially reprocessed date range is left partially reprocessed — which downstream consumers may read as complete. Prefer airflow.backfill_pause when the goal is only to free capacity.","description":"Cancel a backfill. Its queued runs are dropped and running task instances are stopped, so a partially reprocessed date range is left partially reprocessed — which downstream consumers may read as complete. Prefer airflow.backfill_pause when the goal is only to free capacity.","kind":"script","risk":"high","side_effects":["Stops the backfill and cancels its remaining runs.","Task instances still running are terminated mid-flight, which can leave partial writes.","The date range is left partly reprocessed; the backfill cannot be resumed."],"args":[{"name":"backfill_id","type":"integer","required":true,"description":"Backfill id, as reported by airflow.backfills.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Abandon a backfill started with the wrong range","args":{"backfill_id":7}}],"search_terms":["cancel backfill","stop backfill","kill backfill"]},{"id":"airflow.backfill_create","title":"Start a backfill (POST /api/v2/backfills)","summary":"Start a backfill of one DAG over a date range. Airflow creates one run per interval in the range and executes them for real, so a wide range is a large, sustained production load: every task writes what it normally writes and competes for the same pools as scheduled work. Bound it with max_active_runs and check airflow.backfills first.","description":"Start a backfill of one DAG over a date range. Airflow creates one run per interval in the range and executes them for real, so a wide range is a large, sustained production load: every task writes what it normally writes and competes for the same pools as scheduled work. Bound it with max_active_runs and check airflow.backfills first.","kind":"script","risk":"high","side_effects":["Creates one DAG run per interval in the range and executes every task in them.","Sustained consumption of pool, queue, and executor capacity shared with scheduled work.","reprocess_behavior decides whether existing runs in the range are re-run.","Pause or stop it with airflow.backfill_pause or airflow.backfill_cancel."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to backfill.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"from_date","type":"string","required":true,"description":"First logical date in the range, ISO 8601, e.g. 2026-08-01T00:00:00Z.","validation":{"pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$","max_length":40}},{"name":"to_date","type":"string","required":true,"description":"Last logical date in the range, ISO 8601.","validation":{"pattern":"^[0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?$","max_length":40}},{"name":"reprocess_behavior","type":"string","required":false,"default":"none","description":"What to do about intervals that already have a run — none (the default) skips them, failed re-runs the failed ones, completed re-runs every finished one.","validation":{"enum":["none","failed","completed"]}},{"name":"max_active_runs","type":"integer","required":false,"default":3,"description":"How many backfill runs may be in flight at once. Keep it small so scheduled work still gets slots.","validation":{"min":1,"max":100}},{"name":"run_backwards","type":"string","required":false,"default":"false","description":"Process the range newest interval first.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Reprocess one week of failed runs, three at a time","args":{"dag_id":"daily_sales_etl","from_date":"2026-07-29T00:00:00Z","reprocess_behavior":"failed","to_date":"2026-08-05T00:00:00Z"}}],"search_terms":["backfill","rerun a date range","reprocess history","catch up missed runs"]},{"id":"airflow.backfill_pause","title":"Pause a backfill (PUT /api/v2/backfills/{backfill_id}/pause)","summary":"Pause a running backfill so it stops creating further runs. Runs already in flight finish. This is how to give scheduled work its pool slots back without losing the backfill's progress — resume it in the Airflow UI, or cancel it with airflow.backfill_cancel.","description":"Pause a running backfill so it stops creating further runs. Runs already in flight finish. This is how to give scheduled work its pool slots back without losing the backfill's progress — resume it in the Airflow UI, or cancel it with airflow.backfill_cancel.","kind":"script","risk":"medium","side_effects":["Stops the backfill creating new DAG runs.","Backfill runs already in flight continue to completion.","Reversible — the backfill keeps its progress and can be resumed."],"args":[{"name":"backfill_id","type":"integer","required":true,"description":"Backfill id, as reported by airflow.backfills.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Pause a backfill that is starving scheduled runs","args":{"backfill_id":7}}],"search_terms":["pause backfill","stop backfill temporarily","free up slots"]},{"id":"airflow.backfills","title":"List backfills (GET /api/v2/backfills)","summary":"List backfills for one DAG with their date range, reprocess behavior, max_active_runs, and whether each is running, paused, or completed. Read it before starting another backfill — an already-running one is a common source of a saturated pool.","description":"List backfills for one DAG with their date range, reprocess behavior, max_active_runs, and whether each is running, paused, or completed. Read it before starting another backfill — an already-running one is a common source of a saturated pool.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/backfills endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id whose backfills to list.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Backfills returned in this page.","validation":{"min":1,"max":100}},{"name":"order_by","type":"string","required":false,"default":"-id","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Backfills for one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["list backfills","is a backfill running","backfill status"]},{"id":"airflow.connections","title":"List connection inventory (GET /api/v2/connections)","summary":"List Airflow connections by id, type, host, port, schema, and login, plus whether each one carries a password and an extra document. Secrets never leave the runner: the password and the whole extra field — where service account JSON, tokens, and TLS keys live — are dropped before the result is returned, so this answers \"does this connection exist and where does it point\", never \"what is the credential\".","description":"List Airflow connections by id, type, host, port, schema, and login, plus whether each one carries a password and an extra document. Secrets never leave the runner: the password and the whole extra field — where service account JSON, tokens, and TLS keys live — are dropped before the result is returned, so this answers \"does this connection exist and where does it point\", never \"what is the credential\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/connections endpoint.","Read-only — never writes or mutates data.","Returns connection metadata only; passwords and extra fields are removed on the host."],"args":[{"name":"connection_id_pattern","type":"string","required":false,"default":"","description":"Substring the connection id must contain. Empty lists every connection.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Connections returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every connection and where it points","args":{}},{"title":"Warehouse connections","args":{"connection_id_pattern":"warehouse"}}],"search_terms":["list connections","which connection","connection host","conn_id"]},{"id":"airflow.dag","title":"GET /api/v2/dags/{dag_id}","summary":"Show one DAG's summary — paused state, schedule, owners, tags, next run, concurrency limits, and last parse time. Use when you already know the dag_id; airflow.dag_details adds the parsed DAG-level parameters.","description":"Show one DAG's summary — paused state, schedule, owners, tags, next run, concurrency limits, and last parse time. Use when you already know the dag_id; airflow.dag_details adds the parsed DAG-level parameters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Summary for one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag schedule","is the dag paused","next dag run"]},{"id":"airflow.dag_details","title":"GET /api/v2/dags/{dag_id}/details","summary":"Show one DAG's full parsed definition — the summary fields plus timetable, catchup, start and end dates, default arguments, doc_md, params, dataset or asset schedule, and the file it was parsed from. This is what to read before unpausing a DAG, because it says whether catchup will backfill.","description":"Show one DAG's full parsed definition — the summary fields plus timetable, catchup, start and end dates, default arguments, doc_md, params, dataset or asset schedule, and the file it was parsed from. This is what to read before unpausing a DAG, because it says whether catchup will backfill.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/details endpoint.","Read-only — never writes or mutates data.","Includes DAG-level default_args and params as the DAG author wrote them."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Full definition, including catchup","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag catchup","dag timetable","dag default args","dag params"]},{"id":"airflow.dag_pause","title":"Pause a DAG (PATCH /api/v2/dags/{dag_id})","summary":"Pause one DAG so the scheduler stops creating new runs for it. Runs already in flight keep going. This is the standard containment step for a DAG that is failing in a loop or hammering a downstream system, and airflow.dag_unpause reverses it exactly.","description":"Pause one DAG so the scheduler stops creating new runs for it. Runs already in flight keep going. This is the standard containment step for a DAG that is failing in a loop or hammering a downstream system, and airflow.dag_unpause reverses it exactly.","kind":"script","risk":"medium","side_effects":["Sets is_paused true for the DAG; the scheduler creates no further runs.","Runs and task instances already in flight continue to completion.","Fully reversible with airflow.dag_unpause."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to pause.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Pause a DAG that keeps failing","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["pause dag","stop scheduling","stop the dag"]},{"id":"airflow.dag_run","title":"GET /api/v2/dags/{dag_id}/dagRuns/{dag_run_id}","summary":"Show one DAG run — state, run type, logical date, queued/start/end times, duration, the conf it was triggered with, and its note. Use after airflow.dag_runs narrows to the run you care about.","description":"Show one DAG run — state, run type, logical date, queued/start/end times, duration, the conf it was triggered with, and its note. Use after airflow.dag_runs narrows to the run you care about.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/dagRuns/{dag_run_id} endpoint.","Read-only — never writes or mutates data.","Returns the run conf exactly as the trigger supplied it."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id, e.g. scheduled__2026-08-05T00:00:00+00:00 or manual__2026-08-05T09:14:22.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}}],"examples":[{"title":"One scheduled run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["dag run detail","run conf","why is this run queued"]},{"id":"airflow.dag_run_clear","title":"Clear and re-run a DAG run (POST .../dagRuns/{dag_run_id}/clear)","summary":"Clear task instances in one DAG run and let the scheduler run them again. This is the standard \"retry last night's failure\" action, and the cleared tasks execute for real with all their side effects. Run airflow.dag_run_clear_preview first to see exactly what it will touch.","description":"Clear task instances in one DAG run and let the scheduler run them again. This is the standard \"retry last night's failure\" action, and the cleared tasks execute for real with all their side effects. Run airflow.dag_run_clear_preview first to see exactly what it will touch.","kind":"script","risk":"high","side_effects":["Resets the matching task instances and re-queues them for execution.","Cleared tasks run again with their real side effects, including writes and third-party calls.","Sets the DAG run back to a running state."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Clear only failed task instances (true, the default) or every task instance in the run. Clearing everything re-runs tasks that already succeeded.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Retry the failed tasks in a run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["clear dag run","retry failed tasks","rerun the run","restart the run"]},{"id":"airflow.dag_run_clear_preview","title":"Preview clearing a DAG run (POST .../dagRuns/{dag_run_id}/clear, dry run)","summary":"Show which task instances airflow.dag_run_clear would reset, without changing anything. Airflow's clear is a dry run by default, and this action fixes it that way: read the list, confirm the blast radius, then run the real clear.","description":"Show which task instances airflow.dag_run_clear would reset, without changing anything. Airflow's clear is a dry run by default, and this action fixes it that way: read the list, confirm the blast radius, then run the real clear.","kind":"script","risk":"low","side_effects":["One HTTP POST with dry_run fixed true; Airflow computes the affected task instances and changes nothing.","Read-only in effect — no task instance or run state is modified."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Consider only failed task instances (true, the default) or every task instance in the run.","validation":{"enum":["true","false"]}}],"examples":[{"title":"What a retry of the failed tasks would touch","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}}],"search_terms":["what would clearing do","preview retry","dry run clear"]},{"id":"airflow.dag_run_delete","title":"Delete a DAG run (DELETE .../dagRuns/{dag_run_id})","summary":"Delete one DAG run and its task-instance records from the metadata database. Irreversible: the run's history, durations, and notes are gone, and the log files it left behind are orphaned. Use it to clear a run created with a wrong logical date or conf, not to hide a failure — airflow.dag_run_set_state retires a run and keeps the record.","description":"Delete one DAG run and its task-instance records from the metadata database. Irreversible: the run's history, durations, and notes are gone, and the log files it left behind are orphaned. Use it to clear a run created with a wrong logical date or conf, not to hide a failure — airflow.dag_run_set_state retires a run and keeps the record.","kind":"script","risk":"high","side_effects":["Permanently removes the DAG run and its task-instance rows from the metadata database.","Run history, durations, notes, and XCom entries for the run are lost.","Cannot be undone; the scheduler may recreate a scheduled run for the same interval."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id to delete.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}}],"examples":[{"title":"Remove a run triggered with the wrong conf","args":{"dag_id":"daily_sales_etl","dag_run_id":"manual__2026-08-05T09:14:22"}}],"search_terms":["delete dag run","remove a run","drop the run record"]},{"id":"airflow.dag_run_set_state","title":"Set a DAG run's state (PATCH .../dagRuns/{dag_run_id})","summary":"Set one DAG run to queued, success, or failed. Marking a run failed stops the scheduler from starting further tasks in it; marking it success closes it out without running the remaining tasks, which is how a stuck run is retired — and also how work gets silently skipped, so state the reason in the note. Setting it queued makes the scheduler re-examine the run.","description":"Set one DAG run to queued, success, or failed. Marking a run failed stops the scheduler from starting further tasks in it; marking it success closes it out without running the remaining tasks, which is how a stuck run is retired — and also how work gets silently skipped, so state the reason in the note. Setting it queued makes the scheduler re-examine the run.","kind":"script","risk":"high","side_effects":["Changes the run's state in the metadata database.","success or failed ends the run; remaining tasks are not executed.","queued causes the scheduler to re-evaluate and can start tasks again.","Downstream DAGs scheduled on this run's assets react to the new state."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"state","type":"string","required":true,"description":"New run state.","validation":{"enum":["queued","success","failed"]}}],"examples":[{"title":"Retire a run that will never finish","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"failed"}},{"title":"Send a run back to the scheduler","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"queued"}}],"search_terms":["mark run failed","mark run success","stuck dag run","force run to finish"]},{"id":"airflow.dag_run_trigger","title":"Trigger a DAG run (POST /api/v2/dags/{dag_id}/dagRuns)","summary":"Trigger a new run of one DAG. Every task in the DAG executes for real — writes to warehouses, calls to third parties, notifications — so this is a production change, not a test. Supply conf as a JSON object when the DAG reads dag_run.conf.","description":"Trigger a new run of one DAG. Every task in the DAG executes for real — writes to warehouses, calls to third parties, notifications — so this is a production change, not a test. Supply conf as a JSON object when the DAG reads dag_run.conf.","kind":"script","risk":"high","side_effects":["Creates a DAG run and executes the DAG's tasks with their real side effects.","Consumes pool, queue, and executor capacity shared with every other DAG.","Runs even when the DAG is paused."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to trigger.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"logical_date","type":"string","required":false,"default":"","description":"Logical date for the run as an ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z. Empty lets Airflow assign one, which is what an ad-hoc run wants.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Explicit run id. Empty lets Airflow generate a manual__ id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"conf","type":"string","required":false,"default":"","description":"Run configuration as a JSON object, e.g. {\"region\":\"eu\"}. Must parse as JSON; anything else fails before the request is sent.","validation":{"max_length":4096}},{"name":"note","type":"string","required":false,"default":"","description":"Free-text note recorded on the run, e.g. the incident it belongs to.","validation":{"max_length":1000}}],"examples":[{"title":"Run a DAG now","args":{"dag_id":"daily_sales_etl"}},{"title":"Run with configuration and a note","args":{"conf":"{\"region\":\"eu\"}","dag_id":"daily_sales_etl","note":"INC-4821 replay"}}],"search_terms":["trigger dag","run the dag now","manual dag run","rerun the pipeline"]},{"id":"airflow.dag_runs","title":"List DAG runs (GET /api/v2/dags/{dag_id}/dagRuns)","summary":"List DAG runs with their state, run type, queued/start/end times, duration, and who triggered them. Pass `dag_id: \"~\"` to search across every DAG at once — combined with `state: failed` that is the one call that answers \"what failed in the last hour\".","description":"List DAG runs with their state, run type, queued/start/end times, duration, and who triggered them. Pass `dag_id: \"~\"` to search across every DAG at once — combined with `state: failed` that is the one call that answers \"what failed in the last hour\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/dagRuns endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"~","description":"DAG id, or ~ (the default) to search runs across every DAG.","validation":{"pattern":"^([A-Za-z0-9._-]{1,250}|~)$","max_length":250}},{"name":"state","type":"string","required":false,"default":"","description":"Restrict to runs in this state. Empty lists every state.","validation":{"enum":["","queued","running","success","failed"]}},{"name":"run_type","type":"string","required":false,"default":"","description":"Restrict to runs of this type. Empty lists every type.","validation":{"enum":["","backfill","scheduled","manual","operator_triggered","asset_triggered","asset_materialization"]}},{"name":"start_date_gte","type":"string","required":false,"default":"","description":"Only runs that started at or after this ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Runs returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-run_after","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every failed run across the whole deployment","args":{"state":"failed"}},{"title":"Recent runs of one DAG","args":{"dag_id":"daily_sales_etl"}},{"title":"Runs still going right now","args":{"state":"running"}}],"search_terms":["failed runs","running dag runs","recent runs","what failed last night"]},{"id":"airflow.dag_stats","title":"Count DAG runs by state (GET /api/v2/dagStats)","summary":"Count each DAG's runs by state — queued, running, success, failed — in one call. The cheap triage read: it turns \"is anything wrong\" into a number per DAG without walking run lists.","description":"Count each DAG's runs by state — queued, running, success, failed — in one call. The cheap triage read: it turns \"is anything wrong\" into a number per DAG without walking run lists.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dagStats endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_ids","type":"string","required":false,"default":"","description":"Comma-separated dag_ids to count. Empty counts every DAG.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}}],"examples":[{"title":"Run counts for every DAG","args":{}},{"title":"Run counts for two DAGs","args":{"dag_ids":"daily_sales_etl,hourly_ingest"}}],"search_terms":["how many failed runs","queued runs count","dag run summary"]},{"id":"airflow.dag_tasks","title":"List a DAG's tasks (GET /api/v2/dags/{dag_id}/tasks)","summary":"List the tasks a DAG defines, with operator class, pool, queue, retries, trigger rule, and upstream/downstream ids. Read it to learn a DAG's shape before clearing a task or reasoning about which downstream work a failure blocks.","description":"List the tasks a DAG defines, with operator class, pool, queue, retries, trigger rule, and upstream/downstream ids. Read it to learn a DAG's shape before clearing a task or reasoning about which downstream work a failure blocks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags/{dag_id}/tasks endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Tasks in one DAG","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["dag tasks","task dependencies","which operator","task pool"]},{"id":"airflow.dag_unpause","title":"Unpause a DAG (PATCH /api/v2/dags/{dag_id})","summary":"Unpause one DAG so the scheduler resumes creating runs. Higher risk than the pause it reverses: a DAG with catchup enabled and an old start date creates one run per missed interval the moment it is unpaused, which can be hundreds of runs and can saturate every pool. Read airflow.dag_details first and check catchup and max_active_runs.","description":"Unpause one DAG so the scheduler resumes creating runs. Higher risk than the pause it reverses: a DAG with catchup enabled and an old start date creates one run per missed interval the moment it is unpaused, which can be hundreds of runs and can saturate every pool. Read airflow.dag_details first and check catchup and max_active_runs.","kind":"script","risk":"high","side_effects":["Sets is_paused false for the DAG; the scheduler resumes creating runs.","With catchup enabled, immediately schedules every interval missed while paused.","Consumes pool and executor slots shared with every other DAG."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id to unpause.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}}],"examples":[{"title":"Resume a DAG after the fix is deployed","args":{"dag_id":"daily_sales_etl"}}],"search_terms":["unpause dag","resume dag","enable dag","turn the dag back on"]},{"id":"airflow.dag_warnings","title":"List DAG warnings (GET /api/v2/dagWarnings)","summary":"List non-fatal DAG warnings the scheduler recorded — a task referencing a pool that does not exist, an asset conflict, a value that varies between parses. These do not break parsing, so they are invisible until a task queues forever against a missing pool.","description":"List non-fatal DAG warnings the scheduler recorded — a task referencing a pool that does not exist, an asset conflict, a value that varies between parses. These do not break parsing, so they are invisible until a task queues forever against a missing pool.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dagWarnings endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"","description":"Restrict to one DAG. Empty lists warnings for every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Warnings returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"Every recorded DAG warning","args":{}}],"search_terms":["non-existent pool","dag warning","asset conflict"]},{"id":"airflow.dags","title":"List DAGs (GET /api/v2/dags)","summary":"List DAGs with their paused state, schedule, owners, tags, last parse time, and whether they currently have import errors. Filter by name pattern, tag, paused state, or the state of the most recent run — `last_dag_run_state: failed` is the fastest way to see everything that is broken right now.","description":"List DAGs with their paused state, schedule, owners, tags, last parse time, and whether they currently have import errors. Filter by name pattern, tag, paused state, or the state of the most recent run — `last_dag_run_state: failed` is the fastest way to see everything that is broken right now.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/dags endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id_pattern","type":"string","required":false,"default":"","description":"Substring the dag_id must contain. Empty lists every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"tags","type":"string","required":false,"default":"","description":"Comma-separated DAG tags; a DAG matching any of them is included.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,250}$","max_length":250}},{"name":"paused","type":"string","required":false,"default":"","description":"Restrict to paused (true) or unpaused (false) DAGs. Empty lists both.","validation":{"enum":["","true","false"]}},{"name":"last_dag_run_state","type":"string","required":false,"default":"","description":"Restrict to DAGs whose most recent run is in this state.","validation":{"enum":["","queued","running","success","failed"]}},{"name":"exclude_stale","type":"string","required":false,"default":"true","description":"Hide DAGs whose file is no longer present (true, the default) or include them.","validation":{"enum":["true","false"]}},{"name":"limit","type":"integer","required":false,"default":50,"description":"DAGs returned in this page.","validation":{"min":1,"max":200}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset, for walking past the first page.","validation":{"min":0,"max":100000}},{"name":"order_by","type":"string","required":false,"default":"dag_id","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every DAG","args":{}},{"title":"DAGs whose last run failed","args":{"last_dag_run_state":"failed"}},{"title":"One team's DAGs","args":{"tags":"platform,ingest"}}],"search_terms":["list dags","paused dags","failing dags","dags by tag"]},{"id":"airflow.event_logs","title":"List Airflow event log entries (GET /api/v2/eventLogs)","summary":"List Airflow's own audit trail — who paused a DAG, triggered a run, cleared a task, or edited a variable, with the owner and timestamp. Read it to answer \"who changed this and when\" after an unexplained state change.","description":"List Airflow's own audit trail — who paused a DAG, triggered a run, cleared a task, or edited a variable, with the owner and timestamp. Read it to answer \"who changed this and when\" after an unexplained state change.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/eventLogs endpoint.","Read-only — never writes or mutates data.","Discloses which users acted on which DAGs."],"args":[{"name":"dag_id","type":"string","required":false,"default":"","description":"Restrict to events for one DAG. Empty lists every DAG.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"task_id","type":"string","required":false,"default":"","description":"Restrict to events for one task.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"event","type":"string","required":false,"default":"","description":"Restrict to one event name, e.g. trigger, clear, paused.","validation":{"pattern":"^[A-Za-z0-9._-]{0,64}$","max_length":64}},{"name":"after","type":"string","required":false,"default":"","description":"Only events at or after this ISO 8601 timestamp, e.g. 2026-08-05T00:00:00Z.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,6})?(Z|[+-][0-9]{2}:[0-9]{2})?)?)?$","max_length":40}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Events returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-when","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Recent activity across the deployment","args":{}},{"title":"Who paused this DAG","args":{"dag_id":"daily_sales_etl","event":"paused"}}],"search_terms":["who paused the dag","who triggered this","airflow audit log","who cleared the task"]},{"id":"airflow.health","title":"GET /api/v2/monitor/health","summary":"Check Airflow control-plane health — whether the metadata database is reachable and when the scheduler, triggerer, and DAG processor last sent a heartbeat. Start here when DAGs stopped running: a scheduler reporting \"unhealthy\" explains an entire fleet of queued-but-never-started runs. Needs no credentials.","description":"Check Airflow control-plane health — whether the metadata database is reachable and when the scheduler, triggerer, and DAG processor last sent a heartbeat. Start here when DAGs stopped running: a scheduler reporting \"unhealthy\" explains an entire fleet of queued-but-never-started runs. Needs no credentials.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/monitor/health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check scheduler and triggerer health","args":{}}],"search_terms":["scheduler down","dags not running","triggerer heartbeat","airflow unhealthy"]},{"id":"airflow.import_errors","title":"List DAG import errors (GET /api/v2/importErrors)","summary":"List DAG files that failed to parse, with the filename, the timestamp, and the Python traceback. This is the answer to \"my DAG disappeared from the UI\" and to a deploy that silently stopped scheduling: a file with an import error contributes no DAGs at all.","description":"List DAG files that failed to parse, with the filename, the timestamp, and the Python traceback. This is the answer to \"my DAG disappeared from the UI\" and to a deploy that silently stopped scheduling: a file with an import error contributes no DAGs at all.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/importErrors endpoint.","Read-only — never writes or mutates data.","Returns the Python traceback recorded for each failing DAG file."],"args":[{"name":"filename_pattern","type":"string","required":false,"default":"","description":"Substring the DAG file path must contain. Empty lists every import error.","validation":{"pattern":"^[A-Za-z0-9._/-]{0,512}$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Import errors returned in this page.","validation":{"min":1,"max":100}},{"name":"order_by","type":"string","required":false,"default":"-timestamp","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every DAG file that fails to parse","args":{}}],"search_terms":["dag not showing up","broken dag","import error","dag parse failure"]},{"id":"airflow.jobs","title":"List Airflow jobs (GET /api/v2/jobs)","summary":"List Airflow's own scheduler, triggerer, and DAG-processor jobs with their state, hostname, executor class, and last heartbeat. Where airflow.health answers \"is the scheduler healthy\", this answers \"which hosts are running one and which one went quiet\" — the read for a multi-scheduler deployment.","description":"List Airflow's own scheduler, triggerer, and DAG-processor jobs with their state, hostname, executor class, and last heartbeat. Where airflow.health answers \"is the scheduler healthy\", this answers \"which hosts are running one and which one went quiet\" — the read for a multi-scheduler deployment.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/jobs endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"job_type","type":"string","required":false,"default":"","description":"Restrict to one job type, e.g. SchedulerJob, TriggererJob, DagProcessorJob. Empty lists every type.","validation":{"pattern":"^[A-Za-z]{0,64}$","max_length":64}},{"name":"is_alive","type":"string","required":false,"default":"","description":"Restrict to jobs whose heartbeat is current (true) or stale (false). Empty lists both.","validation":{"enum":["","true","false"]}},{"name":"hostname","type":"string","required":false,"default":"","description":"Restrict to jobs running on one host.","validation":{"pattern":"^[A-Za-z0-9._-]{0,253}$","max_length":253}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Jobs returned in this page.","validation":{"min":1,"max":500}},{"name":"order_by","type":"string","required":false,"default":"-latest_heartbeat","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every job, newest heartbeat first","args":{}},{"title":"Schedulers that stopped heartbeating","args":{"is_alive":"false","job_type":"SchedulerJob"}}],"search_terms":["scheduler hosts","triggerer job","stale heartbeat","which scheduler is alive"]},{"id":"airflow.pool_set_slots","title":"Set a pool's slot count (PATCH /api/v2/pools/{pool_name})","summary":"Set how many slots a pool has. This is the throttle: lower it to shed load from a database that is struggling, raise it when the bottleneck is gone. Bounded and reversible — the change applies to scheduling decisions from now on and never touches tasks already running.","description":"Set how many slots a pool has. This is the throttle: lower it to shed load from a database that is struggling, raise it when the bottleneck is gone. Bounded and reversible — the change applies to scheduling decisions from now on and never touches tasks already running.","kind":"script","risk":"medium","side_effects":["Changes the pool's total slots, so the scheduler admits more or fewer tasks.","Lowering slots leaves already-running tasks alone; they finish normally.","Lowering slots below current occupancy queues subsequent tasks until slots free up.","Reversible by setting the previous value again."],"args":[{"name":"pool_name","type":"string","required":true,"description":"Pool to change, as listed by airflow.pools.","validation":{"pattern":"^[A-Za-z0-9._-]{1,256}$","max_length":256}},{"name":"slots","type":"integer","required":true,"description":"New slot count. 0 stops the pool admitting any task; -1 makes it unlimited.","validation":{"min":-1,"max":100000}}],"examples":[{"title":"Halve a pool while the warehouse recovers","args":{"pool_name":"warehouse","slots":4}}],"search_terms":["pool slots","throttle airflow","reduce concurrency","increase parallelism"]},{"id":"airflow.pools","title":"List pools (GET /api/v2/pools)","summary":"List Airflow pools with total slots and how many are occupied, running, queued, scheduled, deferred, and open. A pool with zero open slots is the usual reason tasks sit queued while the scheduler looks healthy.","description":"List Airflow pools with total slots and how many are occupied, running, queued, scheduled, deferred, and open. A pool with zero open slots is the usual reason tasks sit queued while the scheduler looks healthy.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/pools endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"pool_name_pattern","type":"string","required":false,"default":"","description":"Substring the pool name must contain. Empty lists every pool.","validation":{"pattern":"^[A-Za-z0-9._-]{0,256}$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Pools returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every pool and its free slots","args":{}}],"search_terms":["pool slots","tasks stuck queued","pool full","concurrency limit"]},{"id":"airflow.providers","title":"List installed providers (GET /api/v2/providers)","summary":"List the Airflow provider packages installed on the API server with their versions and descriptions. Read it when an operator or a hook behaves differently than the docs say — a provider version mismatch across a fleet is a common cause.","description":"List the Airflow provider packages installed on the API server with their versions and descriptions. Read it when an operator or a hook behaves differently than the docs say — a provider version mismatch across a fleet is a common cause.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/providers endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Providers returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Installed providers and versions","args":{}}],"search_terms":["provider version","installed providers","apache-airflow-providers"]},{"id":"airflow.task_instance","title":"GET .../taskInstances/{task_id}","summary":"Show one task instance — state, try number against max_tries, start and end times, duration, hostname, pool, queue, executor, and the trigger it is deferred on. Read it before clearing a task, to see whether retries are already exhausted.","description":"Show one task instance — state, try number against max_tries, start and end times, duration, hostname, pool, queue, executor, and the trigger it is deferred on. Read it before clearing a task, to see whether retries are already exhausted.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow task-instance endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}}],"examples":[{"title":"One task instance","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_id":"load_warehouse"}},{"title":"One mapped task instance","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","map_index":3,"task_id":"load_partition"}}],"search_terms":["task instance detail","retries left","deferred task"]},{"id":"airflow.task_instance_set_state","title":"Set a task instance's state (PATCH .../taskInstances/{task_id})","summary":"Set one task instance to success, failed, or skipped without running it. Marking a stuck task success unblocks its downstream work — and asserts that the work happened when it did not, so use it only when you have confirmed the effect by other means. failed stops the branch; skipped passes it over.","description":"Set one task instance to success, failed, or skipped without running it. Marking a stuck task success unblocks its downstream work — and asserts that the work happened when it did not, so use it only when you have confirmed the effect by other means. failed stops the branch; skipped passes it over.","kind":"script","risk":"high","side_effects":["Changes the task instance's state in the metadata database without executing the task.","Downstream tasks proceed or stop according to the new state and their trigger rules.","With include_downstream, applies the same state to every downstream task.","Does not perform the work the task would have done."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"state","type":"string","required":true,"description":"New task-instance state.","validation":{"enum":["success","failed","skipped"]}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Apply the same state to every task downstream of this one.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Mark a task that was fixed by hand as done","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","state":"success","task_id":"load_warehouse"}}],"search_terms":["mark task success","mark task failed","skip a task","unblock downstream tasks"]},{"id":"airflow.task_instances","title":"List task instances (GET .../dagRuns/{dag_run_id}/taskInstances)","summary":"List task instances with state, try number, duration, hostname, operator, pool, and queue. Pass `~` for dag_id and dag_run_id to search across every DAG and run: `state: failed` finds every failing task in the deployment, `state: queued` with a pool filter shows what a saturated pool is holding up.","description":"List task instances with state, try number, duration, hostname, operator, pool, and queue. Pass `~` for dag_id and dag_run_id to search across every DAG and run: `state: failed` finds every failing task in the deployment, `state: queued` with a pool filter shows what a saturated pool is holding up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow task-instance list endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"dag_id","type":"string","required":false,"default":"~","description":"DAG id, or ~ (the default) to search across every DAG.","validation":{"pattern":"^([A-Za-z0-9._-]{1,250}|~)$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"~","description":"Run id, or ~ (the default) to search across every run.","validation":{"pattern":"^([A-Za-z0-9._:+-]{1,250}|~)$","max_length":250}},{"name":"task_id","type":"string","required":false,"default":"","description":"Restrict to one task id. Empty lists every task.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"state","type":"string","required":false,"default":"","description":"Restrict to task instances in this state. Empty lists every state.","validation":{"enum":["","removed","scheduled","queued","running","success","restarting","failed","up_for_retry","up_for_reschedule","upstream_failed","skipped","deferred","awaiting_input"]}},{"name":"pool","type":"string","required":false,"default":"","description":"Restrict to task instances assigned to one pool.","validation":{"pattern":"^[A-Za-z0-9._-]{0,256}$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Task instances returned in this page.","validation":{"min":1,"max":200}},{"name":"order_by","type":"string","required":false,"default":"-start_date","description":"Sort field, prefixed with - for descending.","validation":{"pattern":"^-?[a-z_]{1,64}$","max_length":65}}],"examples":[{"title":"Every failed task across the deployment","args":{"state":"failed"}},{"title":"Tasks in one run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00"}},{"title":"What a saturated pool is holding","args":{"pool":"warehouse","state":"queued"}}],"search_terms":["failed tasks","stuck tasks","queued task instances","which task failed","tasks up for retry"]},{"id":"airflow.task_instances_clear","title":"Clear and re-run task instances (POST /api/v2/dags/{dag_id}/clearTaskInstances)","summary":"Clear selected task instances of one DAG and let the scheduler run them again. Narrower than clearing a whole run: name the task ids, optionally one run, and optionally everything downstream. The cleared tasks execute for real. Run airflow.task_instances_clear_preview first.","description":"Clear selected task instances of one DAG and let the scheduler run them again. Narrower than clearing a whole run: name the task ids, optionally one run, and optionally everything downstream. The cleared tasks execute for real. Run airflow.task_instances_clear_preview first.","kind":"script","risk":"high","side_effects":["Resets the matching task instances and re-queues them for execution.","Cleared tasks run again with their real side effects, including writes and third-party calls.","Resets the DAG runs that own the cleared task instances.","With include_downstream, also re-runs every task that depends on the selected ones."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Restrict to one run. Empty clears matching tasks across every run of the DAG.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"task_ids","type":"string","required":false,"default":"","description":"Comma-separated task ids to clear. Empty clears every matching task.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Clear only failed task instances (true, the default) or every matching one. Clearing everything re-runs tasks that already succeeded.","validation":{"enum":["true","false"]}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Also clear every task downstream of the selected ones, so they re-run too.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Retry one failed task in one run","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_ids":"load_warehouse"}}],"search_terms":["clear task","retry one task","rerun task instance","clear downstream tasks"]},{"id":"airflow.task_instances_clear_preview","title":"Preview clearing task instances (POST .../clearTaskInstances, dry run)","summary":"Show which task instances airflow.task_instances_clear would reset, without changing anything. Use it to check the reach of include_downstream before clearing a task in the middle of a DAG.","description":"Show which task instances airflow.task_instances_clear would reset, without changing anything. Use it to check the reach of include_downstream before clearing a task in the middle of a DAG.","kind":"script","risk":"low","side_effects":["One HTTP POST with dry_run fixed true; Airflow computes the affected task instances and changes nothing.","Read-only in effect — no task instance or run state is modified."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":false,"default":"","description":"Restrict to one run. Empty considers every run of the DAG.","validation":{"pattern":"^[A-Za-z0-9._:+-]{0,250}$","max_length":250}},{"name":"task_ids","type":"string","required":false,"default":"","description":"Comma-separated task ids to clear. Empty considers every task.","validation":{"pattern":"^[A-Za-z0-9._,-]{0,1000}$","max_length":1000}},{"name":"only_failed","type":"string","required":false,"default":"true","description":"Consider only failed task instances (true, the default) or every matching task instance.","validation":{"enum":["true","false"]}},{"name":"include_downstream","type":"string","required":false,"default":"false","description":"Also consider every task downstream of the selected ones.","validation":{"enum":["true","false"]}}],"examples":[{"title":"What clearing one task and its downstream would touch","args":{"dag_id":"daily_sales_etl","include_downstream":"true","task_ids":"extract_orders"}}],"search_terms":["what would clearing this task do","preview downstream clear","dry run clear task"]},{"id":"airflow.task_log","title":"Get a task instance log (GET .../logs/{try_number})","summary":"Get the log for one attempt of one task instance, as plain text. This is the read that explains a failure: pick the try number from the task instance's try_number and read the traceback. Airflow's secrets masker hides connection and variable values it knows about; anything else the task printed is returned as written, which is why this needs an approval.","description":"Get the log for one attempt of one task instance, as plain text. This is the read that explains a failure: pick the try number from the task instance's try_number and read the traceback. Airflow's secrets masker hides connection and variable values it knows about; anything else the task printed is returned as written, which is why this needs an approval.","kind":"script","risk":"high","side_effects":["One read-only HTTP GET to the Airflow task-log endpoint.","Read-only — never writes or mutates data.","Returns whatever the task wrote to its log, subject to Airflow's own secrets masking."],"args":[{"name":"dag_id","type":"string","required":true,"description":"DAG id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"dag_run_id","type":"string","required":true,"description":"Run id.","validation":{"pattern":"^[A-Za-z0-9._:+-]{1,250}$","max_length":250}},{"name":"task_id","type":"string","required":true,"description":"Task id.","validation":{"pattern":"^[A-Za-z0-9._-]{1,250}$","max_length":250}},{"name":"try_number","type":"integer","required":true,"description":"Attempt to read, starting at 1. The task instance's try_number is the latest.","validation":{"min":1,"max":1000}},{"name":"map_index","type":"integer","required":false,"default":-1,"description":"Map index for a dynamically mapped task. Leave at -1 for an ordinary task.","validation":{"min":-1,"max":100000}},{"name":"full_content","type":"string","required":false,"default":"true","description":"Return the whole log (true, the default) or only the metadata Airflow streams to the UI.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Log for the latest attempt","args":{"dag_id":"daily_sales_etl","dag_run_id":"scheduled__2026-08-05T00:00:00+00:00","task_id":"load_warehouse","try_number":1}}],"search_terms":["task log","traceback","why did the task fail","stack trace"]},{"id":"airflow.variables","title":"List variable inventory (GET /api/v2/variables)","summary":"List Airflow variable keys with their description, whether they are encrypted, and how many bytes the value holds. Values never leave the runner — an Airflow variable routinely holds an API key or a DSN, and no redaction pattern can be trusted to catch every shape — so this answers \"does this variable exist and is it set\", never \"what is it\".","description":"List Airflow variable keys with their description, whether they are encrypted, and how many bytes the value holds. Values never leave the runner — an Airflow variable routinely holds an API key or a DSN, and no redaction pattern can be trusted to catch every shape — so this answers \"does this variable exist and is it set\", never \"what is it\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/variables endpoint.","Read-only — never writes or mutates data.","Returns variable keys and value length only; values are removed on the host."],"args":[{"name":"variable_key_pattern","type":"string","required":false,"default":"","description":"Substring the variable key must contain. Empty lists every variable.","validation":{"pattern":"^[A-Za-z0-9._-]{0,250}$","max_length":250}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Variables returned in this page.","validation":{"min":1,"max":300}}],"examples":[{"title":"Every variable key","args":{}}],"search_terms":["list variables","is the variable set","variable key"]},{"id":"airflow.version","title":"GET /api/v2/version","summary":"Show the Airflow version and git commit the API server is running. Use it to confirm which release a host is on before reading a version-specific field or filing an upgrade. Needs no credentials.","description":"Show the Airflow version and git commit the API server is running. Use it to confirm which release a host is on before reading a version-specific field or filing an upgrade. Needs no credentials.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Airflow /api/v2/version endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Show the running Airflow version","args":{}}],"search_terms":["airflow version","which release"]}]}],"retired_below":"0.1.1"},{"id":"apache-httpd","name":"Apache HTTPD operations","version":"0.1.16","description":"Apache version, modules, mod_status snapshot, config syntax check, vhost dump, error/access log tails, plus narrow mutators (graceful reload, graceful stop). Full restart not included — use systemd for that.","vendor":"emisar","homepage":"https://emisar.dev/packs/apache-httpd","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/apache-httpd","content_hash":"sha256:248b906ac042e3391fdf8d3ad5a8dea070164aa0703826c9afcab7855cfa2b02","tarball_url":"https://registry.emisar.dev/v1/packs/apache-httpd/0.1.16/248b906ac042e3391fdf8d3ad5a8dea070164aa0703826c9afcab7855cfa2b02/pack.tar.gz","requires":{"os":["linux"],"binaries":["apachectl","curl"]},"detect":{"binaries":[],"processes":["httpd","apache2"],"ports":[]},"setup":{"summary":"Operates on the local Apache instance on the runner host — no credentials needed. Defaults to the Debian/Ubuntu layout; override the paths below only if your install differs.","env":[{"name":"HTTPD_STATUS_URL","description":"mod_status URL the status action fetches (requires mod_status enabled).","default":"http://127.0.0.1/server-status?auto"},{"name":"HTTPD_ERROR_LOG","description":"Path to the Apache error log for error_tail.","default":"/var/log/apache2/error.log"},{"name":"HTTPD_ACCESS_LOG","description":"Path to the Apache access log for the access_top_* actions.","default":"/var/log/apache2/access.log"}],"notes":["Any of `HTTPD_STATUS_URL` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","On RHEL-family installs the logs live under `/var/log/httpd` — set `HTTPD_ERROR_LOG` / `HTTPD_ACCESS_LOG` accordingly."],"host_access":[{"actions":["httpd.modules","httpd.vhosts","httpd.test_config","httpd.graceful_reload","httpd.graceful_stop"],"requirement":"Read protected Apache configuration or signal the root-owned master process.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-apache-httpd-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Apache actions can read private configuration and can stop or reload the web server."}]},{"actions":["httpd.error_tail","httpd.access_top_clients","httpd.access_top_urls"],"requirement":"Read Apache logs through the Debian or Ubuntu system log-reader group.","recipes":[{"name":"Add the Emisar service user to adm","commands":["sudo usermod -aG adm emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx adm","sudo -u emisar test -r /var/log/apache2/error.log"],"impact":"Every process running as emisar can read every host log granted to adm, not only Apache logs. RHEL-family paths need an equivalent persistent log-reader grant."}]}],"verify":"httpd.version"},"actions":[{"id":"httpd.access_top_clients","title":"Top client IPs from access log","summary":"Show a tally of source IPs from the last N access log lines.","description":"Show a tally of source IPs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top clients","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.access_top_urls","title":"Top URLs from access log","summary":"Show a tally of request URLs from the last N access log lines.","description":"Show a tally of request URLs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top URLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.error_tail","title":"tail error_log","summary":"Tail the last N lines from the Apache error log.","description":"Tail the last N lines from the Apache error log.","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines to tail.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${HTTPD_ERROR_LOG:-/var/log/apache2/error.log}\""]}},{"id":"httpd.graceful_reload","title":"apachectl graceful","summary":"Re-read config and gracefully reload child workers — no dropped requests.","description":"Re-read config and gracefully reload child workers — no dropped requests.","kind":"exec","risk":"high","side_effects":["Workers finish in-flight requests, then respawn with the new config.","If new config is invalid, master logs and keeps running old config."],"args":[],"examples":[{"title":"Graceful reload","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful"]}},{"id":"httpd.graceful_stop","title":"apachectl graceful-stop","summary":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","description":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","kind":"exec","risk":"critical","side_effects":["Apache stops accepting new connections.","In-flight requests are allowed to complete.","Workers exit; supervisor must restart to bring back online."],"args":[],"examples":[{"title":"Drain + stop","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful-stop"]}},{"id":"httpd.modules","title":"apachectl -M","summary":"List all loaded modules (static + shared).","description":"List all loaded modules (static + shared).","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-M"]}},{"id":"httpd.status","title":"mod_status snapshot","summary":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","description":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","kind":"exec","risk":"low","side_effects":["One HTTP GET to mod_status.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${HTTPD_STATUS_URL:-http://127.0.0.1/server-status?auto}\""]}},{"id":"httpd.test_config","title":"apachectl -t","summary":"Check config syntax. Run before graceful_reload.","description":"Check config syntax. Run before graceful_reload.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Test config","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-t"]}},{"id":"httpd.version","title":"apachectl -V","summary":"Show Apache version + compiled-in directives + MPM.","description":"Show Apache version + compiled-in directives + MPM.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-V"]}},{"id":"httpd.vhosts","title":"apachectl -S","summary":"List all configured vhosts with their effective listen + ServerName.","description":"List all configured vhosts with their effective listen + ServerName.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-S"]}}],"previous_versions":[{"version":"0.1.12","content_hash":"sha256:dd234d033516cd6f04459b1bb0e52e7e3b6d385c57c1eba44871837e531186a4","tarball_url":"https://registry.emisar.dev/v1/packs/apache-httpd/0.1.12/dd234d033516cd6f04459b1bb0e52e7e3b6d385c57c1eba44871837e531186a4/pack.tar.gz","actions":[{"id":"httpd.access_top_clients","title":"Top client IPs from access log","summary":"Show a tally of source IPs from the last N access log lines.","description":"Show a tally of source IPs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top clients","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.access_top_urls","title":"Top URLs from access log","summary":"Show a tally of request URLs from the last N access log lines.","description":"Show a tally of request URLs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top URLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.error_tail","title":"tail error_log","summary":"Tail the last N lines from the Apache error log.","description":"Tail the last N lines from the Apache error log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines to tail.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${HTTPD_ERROR_LOG:-/var/log/apache2/error.log}\""]}},{"id":"httpd.graceful_reload","title":"apachectl graceful","summary":"Re-read config and gracefully reload child workers — no dropped requests.","description":"Re-read config and gracefully reload child workers — no dropped requests.","kind":"exec","risk":"high","side_effects":["Workers finish in-flight requests, then respawn with the new config.","If new config is invalid, master logs and keeps running old config."],"args":[],"examples":[{"title":"Graceful reload","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful"]}},{"id":"httpd.graceful_stop","title":"apachectl graceful-stop","summary":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","description":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","kind":"exec","risk":"critical","side_effects":["Apache stops accepting new connections.","In-flight requests are allowed to complete.","Workers exit; supervisor must restart to bring back online."],"args":[],"examples":[{"title":"Drain + stop","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful-stop"]}},{"id":"httpd.modules","title":"apachectl -M","summary":"List all loaded modules (static + shared).","description":"List all loaded modules (static + shared).","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-M"]}},{"id":"httpd.status","title":"mod_status snapshot","summary":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","description":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","kind":"exec","risk":"low","side_effects":["One HTTP GET to mod_status.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${HTTPD_STATUS_URL:-http://127.0.0.1/server-status?auto}\""]}},{"id":"httpd.test_config","title":"apachectl -t","summary":"Check config syntax. Run before graceful_reload.","description":"Check config syntax. Run before graceful_reload.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Test config","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-t"]}},{"id":"httpd.version","title":"apachectl -V","summary":"Show Apache version + compiled-in directives + MPM.","description":"Show Apache version + compiled-in directives + MPM.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-V"]}},{"id":"httpd.vhosts","title":"apachectl -S","summary":"List all configured vhosts with their effective listen + ServerName.","description":"List all configured vhosts with their effective listen + ServerName.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-S"]}}]},{"version":"0.1.9","content_hash":"sha256:dc10a005ee7a4b19f24b0f091608b6c2dacc60822e2c0cf989be5b8f033128f0","tarball_url":"https://registry.emisar.dev/v1/packs/apache-httpd/0.1.9/dc10a005ee7a4b19f24b0f091608b6c2dacc60822e2c0cf989be5b8f033128f0/pack.tar.gz","actions":[{"id":"httpd.access_top_clients","title":"Top client IPs from access log","summary":"Show a tally of source IPs from the last N access log lines.","description":"Show a tally of source IPs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top clients","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.access_top_urls","title":"Top URLs from access log","summary":"Show a tally of request URLs from the last N access log lines.","description":"Show a tally of request URLs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top URLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.error_tail","title":"tail error_log","summary":"Tail the last N lines from the Apache error log.","description":"Tail the last N lines from the Apache error log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines to tail.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${HTTPD_ERROR_LOG:-/var/log/apache2/error.log}\""]}},{"id":"httpd.graceful_reload","title":"apachectl graceful","summary":"Re-read config and gracefully reload child workers — no dropped requests.","description":"Re-read config and gracefully reload child workers — no dropped requests.","kind":"exec","risk":"high","side_effects":["Workers finish in-flight requests, then respawn with the new config.","If new config is invalid, master logs and keeps running old config."],"args":[],"examples":[{"title":"Graceful reload","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful"]}},{"id":"httpd.graceful_stop","title":"apachectl graceful-stop","summary":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","description":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","kind":"exec","risk":"critical","side_effects":["Apache stops accepting new connections.","In-flight requests are allowed to complete.","Workers exit; supervisor must restart to bring back online."],"args":[],"examples":[{"title":"Drain + stop","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful-stop"]}},{"id":"httpd.modules","title":"apachectl -M","summary":"List all loaded modules (static + shared).","description":"List all loaded modules (static + shared).","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-M"]}},{"id":"httpd.status","title":"mod_status snapshot","summary":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","description":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","kind":"exec","risk":"low","side_effects":["One HTTP GET to mod_status.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${HTTPD_STATUS_URL:-http://127.0.0.1/server-status?auto}\""]}},{"id":"httpd.test_config","title":"apachectl -t","summary":"Check config syntax. Run before graceful_reload.","description":"Check config syntax. Run before graceful_reload.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Test config","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-t"]}},{"id":"httpd.version","title":"apachectl -V","summary":"Show Apache version + compiled-in directives + MPM.","description":"Show Apache version + compiled-in directives + MPM.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-V"]}},{"id":"httpd.vhosts","title":"apachectl -S","summary":"List all configured vhosts with their effective listen + ServerName.","description":"List all configured vhosts with their effective listen + ServerName.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-S"]}}]},{"version":"0.1.8","content_hash":"sha256:943771bfc1eb4ed4b72696ce6d60a4d9432f10830355cde0d31e62c444704126","tarball_url":"https://registry.emisar.dev/v1/packs/apache-httpd/0.1.8/943771bfc1eb4ed4b72696ce6d60a4d9432f10830355cde0d31e62c444704126/pack.tar.gz","actions":[{"id":"httpd.access_top_clients","title":"Top client IPs from access log","summary":"Show a tally of source IPs from the last N access log lines.","description":"Show a tally of source IPs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top clients","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.access_top_urls","title":"Top URLs from access log","summary":"Show a tally of request URLs from the last N access log lines.","description":"Show a tally of request URLs from the last N access log lines.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many access-log lines to read.","validation":{"min":100,"max":1000000}}],"examples":[{"title":"Top URLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${HTTPD_ACCESS_LOG:-/var/log/apache2/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -rn | head -50\n"]}},{"id":"httpd.error_tail","title":"tail error_log","summary":"Tail the last N lines from the Apache error log.","description":"Tail the last N lines from the Apache error log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines to tail.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${HTTPD_ERROR_LOG:-/var/log/apache2/error.log}\""]}},{"id":"httpd.graceful_reload","title":"apachectl graceful","summary":"Re-read config and gracefully reload child workers — no dropped requests.","description":"Re-read config and gracefully reload child workers — no dropped requests.","kind":"exec","risk":"high","side_effects":["Workers finish in-flight requests, then respawn with the new config.","If new config is invalid, master logs and keeps running old config."],"args":[],"examples":[{"title":"Graceful reload","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful"]}},{"id":"httpd.graceful_stop","title":"apachectl graceful-stop","summary":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","description":"Drain in-flight requests then shut down. Apache will NOT come back automatically; use systemd to restart.","kind":"exec","risk":"critical","side_effects":["Apache stops accepting new connections.","In-flight requests are allowed to complete.","Workers exit; supervisor must restart to bring back online."],"args":[],"examples":[{"title":"Drain + stop","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["graceful-stop"]}},{"id":"httpd.modules","title":"apachectl -M","summary":"List all loaded modules (static + shared).","description":"List all loaded modules (static + shared).","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-M"]}},{"id":"httpd.status","title":"mod_status snapshot","summary":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","description":"Show a snapshot of mod_status (requires mod_status enabled). Set HTTPD_STATUS_URL env var.","kind":"exec","risk":"low","side_effects":["One HTTP GET to mod_status.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS \"${HTTPD_STATUS_URL:-http://127.0.0.1/server-status?auto}\""]}},{"id":"httpd.test_config","title":"apachectl -t","summary":"Check config syntax. Run before graceful_reload.","description":"Check config syntax. Run before graceful_reload.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Test config","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-t"]}},{"id":"httpd.version","title":"apachectl -V","summary":"Show Apache version + compiled-in directives + MPM.","description":"Show Apache version + compiled-in directives + MPM.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-V"]}},{"id":"httpd.vhosts","title":"apachectl -S","summary":"List all configured vhosts with their effective listen + ServerName.","description":"List all configured vhosts with their effective listen + ServerName.","kind":"exec","risk":"low","side_effects":["Forks apachectl.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"apachectl","argv":["-S"]}}]}]},{"id":"artifactory","name":"JFrog Artifactory","version":"0.1.2","description":"JFrog Artifactory ops reads — health, version, license, storage usage, repository listings, artifact info and download stats, background tasks. Read-only. Auth via an access token or Basic credentials on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/artifactory","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/artifactory","content_hash":"sha256:766ef4b581c386af5ed60fa2c082ddc2d190efc04f2126514da7edd2c3e24d77","tarball_url":"https://registry.emisar.dev/v1/packs/artifactory/0.1.2/766ef4b581c386af5ed60fa2c082ddc2d190efc04f2126514da7edd2c3e24d77/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["jf-router"],"ports":[8081,8082]},"setup":{"summary":"Every action calls the Artifactory REST API under `$ARTIFACTORY_URL` via curl. Set `$ARTIFACTORY_TOKEN` for bearer authentication with an access token, or `$ARTIFACTORY_USER` and `$ARTIFACTORY_PASSWORD` for Basic authentication.","env":[{"name":"ARTIFACTORY_URL","description":"JFrog platform base URL (scheme + host + port, no trailing path) — actions append /artifactory/api/... themselves. Defaults to the local platform router.","default":"http://127.0.0.1:8082","example":"https://mycompany.jfrog.io"},{"name":"ARTIFACTORY_TOKEN","description":"Access token sent as the Bearer credential."},{"name":"ARTIFACTORY_USER","description":"User for Basic authentication. Takes precedence over `ARTIFACTORY_TOKEN`.","example":"admin"},{"name":"ARTIFACTORY_PASSWORD","description":"Password paired with `ARTIFACTORY_USER`."}],"notes":["Any Artifactory env var you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","System, storage, and task reads need an admin-scoped identity; repository and artifact reads work with read permission on the target repository.","Every action here works on every edition, OSS included. Repository administration and user listing are Artifactory Pro APIs, so this pack does not ship them."],"verify":"artifactory.ping"},"actions":[{"id":"artifactory.file_info","title":"GET /artifactory/api/storage/<repo>/<path>","summary":"Show one artifact or folder — size, checksums, created/modified times, and for folders the direct children.","description":"Show one artifact or folder — size, checksums, created/modified times, and for folders the direct children.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository key.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"}},{"name":"path","type":"string","required":true,"description":"Artifact or folder path within the repository.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._+/-]{0,254}$"}}],"examples":[{"title":"Artifact info","args":{"path":"com/example/app/1.0.0/app-1.0.0.jar","repo":"libs-release-local"}}],"search_terms":[]},{"id":"artifactory.file_stats","title":"GET /artifactory/api/storage/<repo>/<path>?stats","summary":"Show download stats for one artifact — download count, last downloaded time, and who downloaded it last.","description":"Show download stats for one artifact — download count, last downloaded time, and who downloaded it last.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository key.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"}},{"name":"path","type":"string","required":true,"description":"Artifact path within the repository.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._+/-]{0,254}$"}}],"examples":[{"title":"Download stats","args":{"path":"com/example/app/1.0.0/app-1.0.0.jar","repo":"libs-release-local"}}],"search_terms":["is this artifact still used"]},{"id":"artifactory.license","title":"GET /artifactory/api/system/license","summary":"Show license type, expiry, and licensed-to (never the license key itself).","description":"Show license type, expiry, and licensed-to (never the license key itself).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"License","args":{}}],"search_terms":["artifactory license expired"]},{"id":"artifactory.ping","title":"GET /artifactory/api/system/ping","summary":"Check Artifactory liveness (returns OK when healthy).","description":"Check Artifactory liveness (returns OK when healthy).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Ping","args":{}}],"search_terms":["artifactory down"]},{"id":"artifactory.repositories","title":"GET /artifactory/api/repositories","summary":"List repositories (key, type, package type, URL), optionally filtered by repository class or package type.","description":"List repositories (key, type, package type, URL), optionally filtered by repository class or package type.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"type","type":"string","required":false,"default":"","description":"Repository class filter.","validation":{"enum":["","local","remote","virtual","federated","distribution"]}},{"name":"package_type","type":"string","required":false,"default":"","description":"Package type filter (e.g. maven, docker, npm, generic).","validation":{"pattern":"^[a-z]{0,24}$"}}],"examples":[{"title":"All repositories","args":{}},{"title":"Local docker repositories","args":{"package_type":"docker","type":"local"}}],"search_terms":[]},{"id":"artifactory.storage_summary","title":"GET /artifactory/api/storageinfo","summary":"Show filestore usage totals and the per-repository storage breakdown (size, file and folder counts).","description":"Show filestore usage totals and the per-repository storage breakdown (size, file and folder counts).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Storage summary","args":{}}],"search_terms":["artifactory disk full","artifactory storage usage"]},{"id":"artifactory.tasks","title":"GET /artifactory/api/tasks","summary":"List background tasks (indexing, garbage collection, replication) with their type, state, and schedule.","description":"List background tasks (indexing, garbage collection, replication) with their type, state, and schedule.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Background tasks","args":{}}],"search_terms":["artifactory indexing stuck"]},{"id":"artifactory.version","title":"GET /artifactory/api/system/version","summary":"Show Artifactory version, revision, and enabled addons.","description":"Show Artifactory version, revision, and enabled addons.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:b22ff19806e4f96edbe17d2a0afd7b12fbbb0ce7c3ac94040ff29f29457ecbc2","tarball_url":"https://registry.emisar.dev/v1/packs/artifactory/0.1.0/b22ff19806e4f96edbe17d2a0afd7b12fbbb0ce7c3ac94040ff29f29457ecbc2/pack.tar.gz","actions":[{"id":"artifactory.file_info","title":"GET /artifactory/api/storage/<repo>/<path>","summary":"Show one artifact or folder — size, checksums, created/modified times, and for folders the direct children.","description":"Show one artifact or folder — size, checksums, created/modified times, and for folders the direct children.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository key.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"}},{"name":"path","type":"string","required":true,"description":"Artifact or folder path within the repository.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._+/-]{0,254}$"}}],"examples":[{"title":"Artifact info","args":{"path":"com/example/app/1.0.0/app-1.0.0.jar","repo":"libs-release-local"}}],"search_terms":[]},{"id":"artifactory.file_stats","title":"GET /artifactory/api/storage/<repo>/<path>?stats","summary":"Show download stats for one artifact — download count, last downloaded time, and who downloaded it last.","description":"Show download stats for one artifact — download count, last downloaded time, and who downloaded it last.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository key.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"}},{"name":"path","type":"string","required":true,"description":"Artifact path within the repository.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._+/-]{0,254}$"}}],"examples":[{"title":"Download stats","args":{"path":"com/example/app/1.0.0/app-1.0.0.jar","repo":"libs-release-local"}}],"search_terms":["is this artifact still used"]},{"id":"artifactory.license","title":"GET /artifactory/api/system/license","summary":"Show license type, expiry, and licensed-to (never the license key itself).","description":"Show license type, expiry, and licensed-to (never the license key itself).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"License","args":{}}],"search_terms":["artifactory license expired"]},{"id":"artifactory.ping","title":"GET /artifactory/api/system/ping","summary":"Check Artifactory liveness (returns OK when healthy).","description":"Check Artifactory liveness (returns OK when healthy).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Ping","args":{}}],"search_terms":["artifactory down"]},{"id":"artifactory.repositories","title":"GET /artifactory/api/repositories","summary":"List repositories (key, type, package type, URL), optionally filtered by repository class or package type.","description":"List repositories (key, type, package type, URL), optionally filtered by repository class or package type.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"type","type":"string","required":false,"default":"","description":"Repository class filter.","validation":{"enum":["","local","remote","virtual","federated","distribution"]}},{"name":"package_type","type":"string","required":false,"default":"","description":"Package type filter (e.g. maven, docker, npm, generic).","validation":{"pattern":"^[a-z]{0,24}$"}}],"examples":[{"title":"All repositories","args":{}},{"title":"Local docker repositories","args":{"package_type":"docker","type":"local"}}],"search_terms":[]},{"id":"artifactory.storage_summary","title":"GET /artifactory/api/storageinfo","summary":"Show filestore usage totals and the per-repository storage breakdown (size, file and folder counts).","description":"Show filestore usage totals and the per-repository storage breakdown (size, file and folder counts).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Storage summary","args":{}}],"search_terms":["artifactory disk full","artifactory storage usage"]},{"id":"artifactory.tasks","title":"GET /artifactory/api/tasks","summary":"List background tasks (indexing, garbage collection, replication) with their type, state, and schedule.","description":"List background tasks (indexing, garbage collection, replication) with their type, state, and schedule.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Background tasks","args":{}}],"search_terms":["artifactory indexing stuck"]},{"id":"artifactory.version","title":"GET /artifactory/api/system/version","summary":"Show Artifactory version, revision, and enabled addons.","description":"Show Artifactory version, revision, and enabled addons.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[]}]}]},{"id":"aws-cloudwatch","name":"AWS CloudWatch operations","version":"0.1.11","description":"Metric + alarm + log group + log stream + log query introspection. Read-only. Auth via AWS_PROFILE.","vendor":"emisar","homepage":"https://emisar.dev/packs/aws-cloudwatch","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/aws-cloudwatch","content_hash":"sha256:b8acc2fdc54ce418cdecd8914eeeeec51365bb2916f4c49482be6c6840e137c8","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cloudwatch/0.1.11/b8acc2fdc54ce418cdecd8914eeeeec51365bb2916f4c49482be6c6840e137c8/pack.tar.gz","requires":{"os":["linux"],"binaries":["aws"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the aws CLI on the runner host. It resolves credentials and region from its own environment or `~/.aws` config — the runner only forwards the variables you allowlist in `inherit_env`.","env":[{"name":"AWS_PROFILE","description":"Named profile in `~/.aws/config` and `~/.aws/credentials`. Omit to use the default profile or static-key/instance-role auth.","example":"prod"},{"name":"AWS_REGION","required":true,"description":"Region to query; CloudWatch is regional, so calls fail without it.","example":"us-east-1"},{"name":"AWS_ACCESS_KEY_ID","description":"Static access key. Use instead of a profile; pair with `AWS_SECRET_ACCESS_KEY`."},{"name":"AWS_SECRET_ACCESS_KEY","description":"Secret for `AWS_ACCESS_KEY_ID`."},{"name":"AWS_SESSION_TOKEN","description":"Session token for temporary (STS) credentials."}],"notes":["An EC2 instance role or ECS task role needs no key at all and is the shape to prefer; a static pair is minted from [the IAM users console](https://console.aws.amazon.com/iam/home#/users) → the user → Security credentials → Create access key.","Alternative to env keys: an `~/.aws/credentials` profile (read from disk, no `inherit_env` entry) or, on EC2/ECS, the instance/task role from instance metadata (no credentials needed at all).","Principal needs read access to CloudWatch and Logs (e.g. cloudwatch:DescribeAlarms / GetMetricStatistics / ListMetrics and logs:DescribeLogGroups / DescribeLogStreams / GetLogEvents / FilterLogEvents)."],"verify":"cw.describe_alarms"},"actions":[{"id":"cw.alarms_in_alarm","title":"aws cloudwatch describe-alarms --state-value ALARM","summary":"List only currently-firing alarms.","description":"List only currently-firing alarms.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Firing alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--state-value","ALARM","--output","json"]}},{"id":"cw.describe_alarms","title":"aws cloudwatch describe-alarms","summary":"List all CloudWatch alarms with state + threshold.","description":"List all CloudWatch alarms with state + threshold.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--output","json"]}},{"id":"cw.get_metric_statistics","title":"aws cloudwatch get-metric-statistics (last 1h)","summary":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","description":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}},{"name":"metric","type":"string","required":true,"description":"Metric name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"CPU last 1h","args":{"metric":"CPUUtilization","namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%dT%H:%M:%SZ); START=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-1H +%Y-%m-%dT%H:%M:%SZ); aws cloudwatch get-metric-statistics --namespace ''\"$1\"'' --metric-name ''\"$2\"'' --start-time $START --end-time $END --period 300 --statistics Average Maximum --output json","emisar","{{ args.namespace }}","{{ args.metric }}"]}},{"id":"cw.list_metrics","title":"aws cloudwatch list-metrics --namespace","summary":"List all metrics in one namespace.","description":"List all metrics in one namespace.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"e.g. AWS/EC2, AWS/RDS, custom/app.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}}],"examples":[{"title":"EC2 metrics","args":{"namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","list-metrics","--namespace","{{ args.namespace }}","--output","json"]}},{"id":"cw.log_groups","title":"aws logs describe-log-groups","summary":"List all CloudWatch log groups.","description":"List all CloudWatch log groups.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Log groups","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-groups","--output","json"]}},{"id":"cw.log_streams","title":"aws logs describe-log-streams","summary":"List streams for one log group, sorted by last event time.","description":"List streams for one log group, sorted by last event time.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_./#\\-]{1,512}$"}}],"examples":[{"title":"Streams","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-streams","--log-group-name","{{ args.log_group }}","--order-by","LastEventTime","--descending","--max-items","50","--output","json"]}},{"id":"cw.log_tail","title":"aws logs tail","summary":"Tail recent log events for one log group (no follow).","description":"Tail recent log events for one log group (no follow).","kind":"exec","risk":"medium","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_/][a-zA-Z0-9_./#\\-]{0,511}$"}},{"name":"since","type":"string","required":false,"default":"1h","description":"How far back: 30m, 1h, 6h, 24h.","validation":{"pattern":"^[0-9]{1,4}[mhd]$"}}],"examples":[{"title":"Last hour","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","tail","{{ args.log_group }}","--since","{{ args.since }}","--format","short"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:6a117f724432894971c9f64e0bac46d40c5ff3839225fe82c6c13f89486d16a7","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cloudwatch/0.1.10/6a117f724432894971c9f64e0bac46d40c5ff3839225fe82c6c13f89486d16a7/pack.tar.gz","actions":[{"id":"cw.alarms_in_alarm","title":"aws cloudwatch describe-alarms --state-value ALARM","summary":"List only currently-firing alarms.","description":"List only currently-firing alarms.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Firing alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--state-value","ALARM","--output","json"]}},{"id":"cw.describe_alarms","title":"aws cloudwatch describe-alarms","summary":"List all CloudWatch alarms with state + threshold.","description":"List all CloudWatch alarms with state + threshold.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--output","json"]}},{"id":"cw.get_metric_statistics","title":"aws cloudwatch get-metric-statistics (last 1h)","summary":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","description":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}},{"name":"metric","type":"string","required":true,"description":"Metric name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"CPU last 1h","args":{"metric":"CPUUtilization","namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%dT%H:%M:%SZ); START=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-1H +%Y-%m-%dT%H:%M:%SZ); aws cloudwatch get-metric-statistics --namespace ''\"$1\"'' --metric-name ''\"$2\"'' --start-time $START --end-time $END --period 300 --statistics Average Maximum --output json","emisar","{{ args.namespace }}","{{ args.metric }}"]}},{"id":"cw.list_metrics","title":"aws cloudwatch list-metrics --namespace","summary":"List all metrics in one namespace.","description":"List all metrics in one namespace.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"e.g. AWS/EC2, AWS/RDS, custom/app.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}}],"examples":[{"title":"EC2 metrics","args":{"namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","list-metrics","--namespace","{{ args.namespace }}","--output","json"]}},{"id":"cw.log_groups","title":"aws logs describe-log-groups","summary":"List all CloudWatch log groups.","description":"List all CloudWatch log groups.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Log groups","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-groups","--output","json"]}},{"id":"cw.log_streams","title":"aws logs describe-log-streams","summary":"List streams for one log group, sorted by last event time.","description":"List streams for one log group, sorted by last event time.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_./#\\-]{1,512}$"}}],"examples":[{"title":"Streams","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-streams","--log-group-name","{{ args.log_group }}","--order-by","LastEventTime","--descending","--max-items","50","--output","json"]}},{"id":"cw.log_tail","title":"aws logs tail","summary":"Tail recent log events for one log group (no follow).","description":"Tail recent log events for one log group (no follow).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_/][a-zA-Z0-9_./#\\-]{0,511}$"}},{"name":"since","type":"string","required":false,"default":"1h","description":"How far back: 30m, 1h, 6h, 24h.","validation":{"pattern":"^[0-9]{1,4}[mhd]$"}}],"examples":[{"title":"Last hour","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","tail","{{ args.log_group }}","--since","{{ args.since }}","--format","short"]}}]},{"version":"0.1.5","content_hash":"sha256:137d4e005c2d37cce215c350875aca703db5ae114b89bc0fd1e426bab19937af","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cloudwatch/0.1.5/137d4e005c2d37cce215c350875aca703db5ae114b89bc0fd1e426bab19937af/pack.tar.gz","actions":[{"id":"cw.alarms_in_alarm","title":"aws cloudwatch describe-alarms --state-value ALARM","summary":"List only currently-firing alarms.","description":"List only currently-firing alarms.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Firing alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--state-value","ALARM","--output","json"]}},{"id":"cw.describe_alarms","title":"aws cloudwatch describe-alarms","summary":"List all CloudWatch alarms with state + threshold.","description":"List all CloudWatch alarms with state + threshold.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--output","json"]}},{"id":"cw.get_metric_statistics","title":"aws cloudwatch get-metric-statistics (last 1h)","summary":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","description":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}},{"name":"metric","type":"string","required":true,"description":"Metric name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"CPU last 1h","args":{"metric":"CPUUtilization","namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%dT%H:%M:%SZ); START=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-1H +%Y-%m-%dT%H:%M:%SZ); aws cloudwatch get-metric-statistics --namespace ''\"$1\"'' --metric-name ''\"$2\"'' --start-time $START --end-time $END --period 300 --statistics Average Maximum --output json","emisar","{{ args.namespace }}","{{ args.metric }}"]}},{"id":"cw.list_metrics","title":"aws cloudwatch list-metrics --namespace","summary":"List all metrics in one namespace.","description":"List all metrics in one namespace.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"e.g. AWS/EC2, AWS/RDS, custom/app.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}}],"examples":[{"title":"EC2 metrics","args":{"namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","list-metrics","--namespace","{{ args.namespace }}","--output","json"]}},{"id":"cw.log_groups","title":"aws logs describe-log-groups","summary":"List all CloudWatch log groups.","description":"List all CloudWatch log groups.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Log groups","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-groups","--output","json"]}},{"id":"cw.log_streams","title":"aws logs describe-log-streams","summary":"List streams for one log group, sorted by last event time.","description":"List streams for one log group, sorted by last event time.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_./#\\-]{1,512}$"}}],"examples":[{"title":"Streams","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-streams","--log-group-name","{{ args.log_group }}","--order-by","LastEventTime","--descending","--max-items","50","--output","json"]}},{"id":"cw.log_tail","title":"aws logs tail","summary":"Tail recent log events for one log group (no follow).","description":"Tail recent log events for one log group (no follow).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_/][a-zA-Z0-9_./#\\-]{0,511}$"}},{"name":"since","type":"string","required":false,"default":"1h","description":"How far back: 30m, 1h, 6h, 24h.","validation":{"pattern":"^[0-9]{1,4}[mhd]$"}}],"examples":[{"title":"Last hour","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","tail","{{ args.log_group }}","--since","{{ args.since }}","--format","short"]}}]},{"version":"0.1.4","content_hash":"sha256:aaae29ea01c91b219528dd15a03246db79a7d6db82892b2d2b5ba1a01f83e4db","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cloudwatch/0.1.4/aaae29ea01c91b219528dd15a03246db79a7d6db82892b2d2b5ba1a01f83e4db/pack.tar.gz","actions":[{"id":"cw.alarms_in_alarm","title":"aws cloudwatch describe-alarms --state-value ALARM","summary":"List only currently-firing alarms.","description":"List only currently-firing alarms.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Firing alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--state-value","ALARM","--output","json"]}},{"id":"cw.describe_alarms","title":"aws cloudwatch describe-alarms","summary":"List all CloudWatch alarms with state + threshold.","description":"List all CloudWatch alarms with state + threshold.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All alarms","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","describe-alarms","--output","json"]}},{"id":"cw.get_metric_statistics","title":"aws cloudwatch get-metric-statistics (last 1h)","summary":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","description":"Get 1-hour Average + Max for one metric. Use for quick health snapshots.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}},{"name":"metric","type":"string","required":true,"description":"Metric name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"CPU last 1h","args":{"metric":"CPUUtilization","namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%dT%H:%M:%SZ); START=$(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-1H +%Y-%m-%dT%H:%M:%SZ); aws cloudwatch get-metric-statistics --namespace ''\"$1\"'' --metric-name ''\"$2\"'' --start-time $START --end-time $END --period 300 --statistics Average Maximum --output json","emisar","{{ args.namespace }}","{{ args.metric }}"]}},{"id":"cw.list_metrics","title":"aws cloudwatch list-metrics --namespace","summary":"List all metrics in one namespace.","description":"List all metrics in one namespace.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"e.g. AWS/EC2, AWS/RDS, custom/app.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,255}$"}}],"examples":[{"title":"EC2 metrics","args":{"namespace":"AWS/EC2"}}],"search_terms":[],"command":{"binary":"aws","argv":["cloudwatch","list-metrics","--namespace","{{ args.namespace }}","--output","json"]}},{"id":"cw.log_groups","title":"aws logs describe-log-groups","summary":"List all CloudWatch log groups.","description":"List all CloudWatch log groups.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Log groups","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-groups","--output","json"]}},{"id":"cw.log_streams","title":"aws logs describe-log-streams","summary":"List streams for one log group, sorted by last event time.","description":"List streams for one log group, sorted by last event time.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_./#\\-]{1,512}$"}}],"examples":[{"title":"Streams","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","describe-log-streams","--log-group-name","{{ args.log_group }}","--order-by","LastEventTime","--descending","--max-items","50","--output","json"]}},{"id":"cw.log_tail","title":"aws logs tail","summary":"Tails recent log events for one log group (no follow).","description":"Tails recent log events for one log group (no follow).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"log_group","type":"string","required":true,"description":"Log group name.","validation":{"pattern":"^[a-zA-Z0-9_/][a-zA-Z0-9_./#\\-]{0,511}$"}},{"name":"since","type":"string","required":false,"default":"1h","description":"How far back: 30m, 1h, 6h, 24h.","validation":{"pattern":"^[0-9]{1,4}[mhd]$"}}],"examples":[{"title":"Last hour","args":{"log_group":"/aws/lambda/my-fn"}}],"search_terms":[],"command":{"binary":"aws","argv":["logs","tail","{{ args.log_group }}","--since","{{ args.since }}","--format","short"]}}]}],"retired_below":"0.1.3"},{"id":"aws-cost","name":"AWS Cost Explorer operations","version":"0.1.7","description":"Read-only AWS spend introspection — month-to-date by service, by account, forecast. Auth via AWS_PROFILE with ce:* permissions. Cost Explorer must be enabled.","vendor":"emisar","homepage":"https://emisar.dev/packs/aws-cost","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/aws-cost","content_hash":"sha256:ae8f0d31aa96de92de2b1f2dd109d6311c743ac6b487459747a097a4829d109f","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cost/0.1.7/ae8f0d31aa96de92de2b1f2dd109d6311c743ac6b487459747a097a4829d109f/pack.tar.gz","requires":{"os":["linux"],"binaries":["aws"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the aws CLI on the runner host. It resolves credentials from its own environment or `~/.aws` config — the runner only forwards the variables you allowlist in `inherit_env`.","env":[{"name":"AWS_PROFILE","description":"Named profile in `~/.aws/config` and `~/.aws/credentials`. Omit to use the default profile or static-key/instance-role auth.","example":"prod"},{"name":"AWS_ACCESS_KEY_ID","description":"Static access key. Use instead of a profile; pair with `AWS_SECRET_ACCESS_KEY`."},{"name":"AWS_SECRET_ACCESS_KEY","description":"Secret for `AWS_ACCESS_KEY_ID`."},{"name":"AWS_SESSION_TOKEN","description":"Session token for temporary (STS) credentials."}],"notes":["Cost Explorer is a global service, so no region is required.","Cost Explorer must be enabled for the account, and the principal needs Cost Explorer read permissions (ce:GetCostAndUsage, ce:GetCostForecast, ce:GetSavingsPlansCoverage).","Alternative to env keys: an `~/.aws/credentials` profile (read from disk, no `inherit_env` entry) or, on EC2/ECS, the instance/task role from instance metadata (no credentials needed at all)."],"verify":"ce.mtd_by_service"},"actions":[{"id":"ce.forecast_current_month","title":"Forecast current-month spend","summary":"Show AWS-projected total spend for the current month based on usage so far.","description":"Show AWS-projected total spend for the current month based on usage so far.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"This month forecast","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-%d); END=$(date -u -d 'first day of next month' +%Y-%m-%d 2>/dev/null || date -u -v+1m -v1d +%Y-%m-%d); aws ce get-cost-forecast --time-period Start=$START,End=$END --metric UNBLENDED_COST --granularity MONTHLY --output json"]}},{"id":"ce.last_7d_daily","title":"Last-7-day daily totals","summary":"Show daily unblended cost for the last 7 days. Use to spot spend spikes.","description":"Show daily unblended cost for the last 7 days. Use to spot spend spikes.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"7-day daily","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%d); START=$(date -u -d '7 days ago' +%Y-%m-%d 2>/dev/null || date -u -v-7d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity DAILY --metrics UnblendedCost --output json"]}},{"id":"ce.mtd_by_account","title":"Month-to-date cost by linked account","summary":"Show MTD cost grouped by linked account ID (org master account view).","description":"Show MTD cost grouped by linked account ID (org master account view).","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"MTD by linked account","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-01); END=$(date -u -d tomorrow +%Y-%m-%d 2>/dev/null || date -u -v+1d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=LINKED_ACCOUNT --output json"]}},{"id":"ce.mtd_by_service","title":"Month-to-date cost by service","summary":"Show unblended cost from the 1st of this month until today, grouped by service.","description":"Show unblended cost from the 1st of this month until today, grouped by service.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"MTD by service","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-01); END=$(date -u -d tomorrow +%Y-%m-%d 2>/dev/null || date -u -v+1d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=SERVICE --output json"]}},{"id":"ce.savings_plans_coverage","title":"Savings Plans coverage (last month)","summary":"Show what fraction of eligible compute spend was covered by Savings Plans / RI last month.","description":"Show what fraction of eligible compute spend was covered by Savings Plans / RI last month.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"SP coverage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-01); START=$(date -u -d 'last month 1st' +%Y-%m-01 2>/dev/null || date -u -v-1m -v1d +%Y-%m-01); aws ce get-savings-plans-coverage --time-period Start=$START,End=$END --granularity MONTHLY --output json"]}}],"previous_versions":[{"version":"0.1.4","content_hash":"sha256:917368aa522ffcc755a6ed0101aea836de28246f045eda6ef6905344715b2d5e","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cost/0.1.4/917368aa522ffcc755a6ed0101aea836de28246f045eda6ef6905344715b2d5e/pack.tar.gz","actions":[{"id":"ce.forecast_current_month","title":"Forecast current-month spend","summary":"Show AWS-projected total spend for the current month based on usage so far.","description":"Show AWS-projected total spend for the current month based on usage so far.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"This month forecast","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-%d); END=$(date -u -d 'first day of next month' +%Y-%m-%d 2>/dev/null || date -u -v+1m -v1d +%Y-%m-%d); aws ce get-cost-forecast --time-period Start=$START,End=$END --metric UNBLENDED_COST --granularity MONTHLY --output json"]}},{"id":"ce.last_7d_daily","title":"Last-7-day daily totals","summary":"Show daily unblended cost for the last 7 days. Use to spot spend spikes.","description":"Show daily unblended cost for the last 7 days. Use to spot spend spikes.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"7-day daily","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%d); START=$(date -u -d '7 days ago' +%Y-%m-%d 2>/dev/null || date -u -v-7d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity DAILY --metrics UnblendedCost --output json"]}},{"id":"ce.mtd_by_account","title":"Month-to-date cost by linked account","summary":"Show MTD cost grouped by linked account ID (org master account view).","description":"Show MTD cost grouped by linked account ID (org master account view).","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"MTD by linked account","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-01); END=$(date -u -d tomorrow +%Y-%m-%d 2>/dev/null || date -u -v+1d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=LINKED_ACCOUNT --output json"]}},{"id":"ce.mtd_by_service","title":"Month-to-date cost by service","summary":"Show unblended cost from the 1st of this month until today, grouped by service.","description":"Show unblended cost from the 1st of this month until today, grouped by service.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"MTD by service","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-01); END=$(date -u -d tomorrow +%Y-%m-%d 2>/dev/null || date -u -v+1d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=SERVICE --output json"]}},{"id":"ce.savings_plans_coverage","title":"Savings Plans coverage (last month)","summary":"Show what fraction of eligible compute spend was covered by Savings Plans / RI last month.","description":"Show what fraction of eligible compute spend was covered by Savings Plans / RI last month.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"SP coverage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-01); START=$(date -u -d 'last month 1st' +%Y-%m-01 2>/dev/null || date -u -v-1m -v1d +%Y-%m-01); aws ce get-savings-plans-coverage --time-period Start=$START,End=$END --granularity MONTHLY --output json"]}}]},{"version":"0.1.3","content_hash":"sha256:316a5685d9733bae33cf8bbdd9ff16b8b274203d4883943d43ae27500d0c72d4","tarball_url":"https://registry.emisar.dev/v1/packs/aws-cost/0.1.3/316a5685d9733bae33cf8bbdd9ff16b8b274203d4883943d43ae27500d0c72d4/pack.tar.gz","actions":[{"id":"ce.forecast_current_month","title":"Forecast current-month spend","summary":"Show AWS-projected total spend for the current month based on usage so far.","description":"Show AWS-projected total spend for the current month based on usage so far.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"This month forecast","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-%d); END=$(date -u -d 'first day of next month' +%Y-%m-%d 2>/dev/null || date -u -v+1m -v1d +%Y-%m-%d); aws ce get-cost-forecast --time-period Start=$START,End=$END --metric UNBLENDED_COST --granularity MONTHLY --output json"]}},{"id":"ce.last_7d_daily","title":"Last-7-day daily totals","summary":"Show daily unblended cost for the last 7 days. Use to spot spend spikes.","description":"Show daily unblended cost for the last 7 days. Use to spot spend spikes.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"7-day daily","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-%d); START=$(date -u -d '7 days ago' +%Y-%m-%d 2>/dev/null || date -u -v-7d +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity DAILY --metrics UnblendedCost --output json"]}},{"id":"ce.mtd_by_account","title":"Month-to-date cost by linked account","summary":"Show MTD cost grouped by linked account ID (org master account view).","description":"Show MTD cost grouped by linked account ID (org master account view).","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"MTD by linked account","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-01); END=$(date -u -d tomorrow +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=LINKED_ACCOUNT --output json"]}},{"id":"ce.mtd_by_service","title":"Month-to-date cost by service","summary":"Show unblended cost from the 1st of this month until today, grouped by service.","description":"Show unblended cost from the 1st of this month until today, grouped by service.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"MTD by service","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","START=$(date -u +%Y-%m-01); END=$(date -u -d tomorrow +%Y-%m-%d); aws ce get-cost-and-usage --time-period Start=$START,End=$END --granularity MONTHLY --metrics UnblendedCost --group-by Type=DIMENSION,Key=SERVICE --output json"]}},{"id":"ce.savings_plans_coverage","title":"Savings Plans coverage (last month)","summary":"Show what fraction of eligible compute spend was covered by Savings Plans / RI last month.","description":"Show what fraction of eligible compute spend was covered by Savings Plans / RI last month.","kind":"exec","risk":"low","side_effects":["One Cost Explorer call.","Read-only."],"args":[],"examples":[{"title":"SP coverage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","END=$(date -u +%Y-%m-01); START=$(date -u -d 'last month 1st' +%Y-%m-01 2>/dev/null || date -u -v-1m -v1d +%Y-%m-01); aws ce get-savings-plans-coverage --time-period Start=$START,End=$END --granularity MONTHLY --output json"]}}]}]},{"id":"aws-ec2","name":"AWS EC2 operations","version":"0.1.10","description":"EC2 instance inventory + state introspection plus narrow mutators (stop, start, reboot, terminate). Auth via AWS_PROFILE + AWS_REGION on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/aws-ec2","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/aws-ec2","content_hash":"sha256:5a0a21f760a823cf574b91831fb702b994f13e14f1aea69fad441e581ac027b5","tarball_url":"https://registry.emisar.dev/v1/packs/aws-ec2/0.1.10/5a0a21f760a823cf574b91831fb702b994f13e14f1aea69fad441e581ac027b5/pack.tar.gz","requires":{"os":["linux"],"binaries":["aws"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the aws CLI on the runner host. It resolves credentials and region from its own environment or `~/.aws` config — the runner only forwards the variables you allowlist in `inherit_env`.","env":[{"name":"AWS_PROFILE","description":"Named profile in `~/.aws/config` and `~/.aws/credentials`. Omit to use the default profile or static-key/instance-role auth.","example":"prod"},{"name":"AWS_REGION","required":true,"description":"Region to operate in; EC2 is regional, so calls fail without it.","example":"us-east-1"},{"name":"AWS_ACCESS_KEY_ID","description":"Static access key. Use instead of a profile; pair with `AWS_SECRET_ACCESS_KEY`."},{"name":"AWS_SECRET_ACCESS_KEY","description":"Secret for `AWS_ACCESS_KEY_ID`."},{"name":"AWS_SESSION_TOKEN","description":"Session token for temporary (STS) credentials."}],"notes":["An EC2 instance role or ECS task role needs no key at all and is the shape to prefer; a static pair is minted from [the IAM users console](https://console.aws.amazon.com/iam/home#/users) → the user → Security credentials → Create access key.","Alternative to env keys: an `~/.aws/credentials` profile (read from disk, no `inherit_env` entry) or, on EC2/ECS, the instance/task role from instance metadata (no credentials needed at all).","Inventory needs ec2:Describe* (read-only). The mutators stop_instance / start_instance / reboot_instance / terminate_instance additionally need ec2:StopInstances / StartInstances / RebootInstances / TerminateInstances."],"verify":"ec2.describe_instances"},"actions":[{"id":"ec2.console_output","title":"aws ec2 get-console-output","summary":"Get serial console output for one instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Useful for boot diagnostics.","description":"Get serial console output for one instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Useful for boot diagnostics.","kind":"exec","risk":"medium","side_effects":["One API call.","Read-only.","Returns guest-written serial output and may expose data the guest logged."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Boot log","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","get-console-output","--instance-id","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instance_one","title":"aws ec2 describe-instances --instance-ids","summary":"Get details for one EC2 instance.","description":"Get details for one EC2 instance.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"i-xxxxxxxx[xxxxxxxxx]","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"One","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instances","title":"aws ec2 describe-instances","summary":"List all EC2 instances in the configured region with state + tags + IPs.","description":"List all EC2 instances in the configured region with state + tags + IPs.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All instances","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--output","json"]}},{"id":"ec2.describe_security_groups","title":"aws ec2 describe-security-groups","summary":"List all SGs with ingress/egress rules.","description":"List all SGs with ingress/egress rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All SGs","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-security-groups","--output","json"]}},{"id":"ec2.describe_subnets","title":"aws ec2 describe-subnets","summary":"List all subnets in this region.","description":"List all subnets in this region.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Subnets","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-subnets","--output","json"]}},{"id":"ec2.describe_volumes","title":"aws ec2 describe-volumes","summary":"List all EBS volumes with size + state + attachment.","description":"List all EBS volumes with size + state + attachment.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-volumes","--output","json"]}},{"id":"ec2.instance_status","title":"aws ec2 describe-instance-status","summary":"Show per-instance system + instance status checks.","description":"Show per-instance system + instance status checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Instance status checks","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instance-status","--include-all-instances","--output","json"]}},{"id":"ec2.reboot_instance","title":"aws ec2 reboot-instances","summary":"Reboot one instance. Instance keeps its IPs + ephemeral storage.","description":"Reboot one instance. Instance keeps its IPs + ephemeral storage.","kind":"exec","risk":"high","side_effects":["Instance reboots; ephemeral storage and IPs persist.","Brief downtime — services on host go down with it."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Reboot one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","reboot-instances","--instance-ids","{{ args.instance_id }}"]}},{"id":"ec2.start_instance","title":"aws ec2 start-instances","summary":"Start one stopped instance.","description":"Start one stopped instance.","kind":"exec","risk":"high","side_effects":["Instance begins booting; billing resumes.","New public IPv4 unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Start one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","start-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.stop_instance","title":"aws ec2 stop-instances","summary":"Stop one instance. Public IP is released (use Elastic IP to retain).","description":"Stop one instance. Public IP is released (use Elastic IP to retain).","kind":"exec","risk":"high","side_effects":["Instance powers off; not billed for compute hours while stopped.","Public IPv4 address is lost unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Stop one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","stop-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.terminate_instance","title":"aws ec2 terminate-instances","summary":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","description":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","kind":"exec","risk":"critical","side_effects":["Instance is shutdown then DELETED.","All non-EBS storage (instance store) is lost.","EBS volumes with DeleteOnTermination=true are deleted too."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Terminate one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","terminate-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:ed1801cb101ba2a0d5273d18ba672e5ebb6db292b758ebf204239e16c1ce64b7","tarball_url":"https://registry.emisar.dev/v1/packs/aws-ec2/0.1.9/ed1801cb101ba2a0d5273d18ba672e5ebb6db292b758ebf204239e16c1ce64b7/pack.tar.gz","actions":[{"id":"ec2.console_output","title":"aws ec2 get-console-output","summary":"Get serial console output for one instance. Useful for boot diagnostics.","description":"Get serial console output for one instance. Useful for boot diagnostics.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Boot log","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","get-console-output","--instance-id","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instance_one","title":"aws ec2 describe-instances --instance-ids","summary":"Get details for one EC2 instance.","description":"Get details for one EC2 instance.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"i-xxxxxxxx[xxxxxxxxx]","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"One","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instances","title":"aws ec2 describe-instances","summary":"List all EC2 instances in the configured region with state + tags + IPs.","description":"List all EC2 instances in the configured region with state + tags + IPs.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All instances","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--output","json"]}},{"id":"ec2.describe_security_groups","title":"aws ec2 describe-security-groups","summary":"List all SGs with ingress/egress rules.","description":"List all SGs with ingress/egress rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All SGs","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-security-groups","--output","json"]}},{"id":"ec2.describe_subnets","title":"aws ec2 describe-subnets","summary":"List all subnets in this region.","description":"List all subnets in this region.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Subnets","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-subnets","--output","json"]}},{"id":"ec2.describe_volumes","title":"aws ec2 describe-volumes","summary":"List all EBS volumes with size + state + attachment.","description":"List all EBS volumes with size + state + attachment.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-volumes","--output","json"]}},{"id":"ec2.instance_status","title":"aws ec2 describe-instance-status","summary":"Show per-instance system + instance status checks.","description":"Show per-instance system + instance status checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Instance status checks","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instance-status","--include-all-instances","--output","json"]}},{"id":"ec2.reboot_instance","title":"aws ec2 reboot-instances","summary":"Reboot one instance. Instance keeps its IPs + ephemeral storage.","description":"Reboot one instance. Instance keeps its IPs + ephemeral storage.","kind":"exec","risk":"high","side_effects":["Instance reboots; ephemeral storage and IPs persist.","Brief downtime — services on host go down with it."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Reboot one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","reboot-instances","--instance-ids","{{ args.instance_id }}"]}},{"id":"ec2.start_instance","title":"aws ec2 start-instances","summary":"Start one stopped instance.","description":"Start one stopped instance.","kind":"exec","risk":"high","side_effects":["Instance begins booting; billing resumes.","New public IPv4 unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Start one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","start-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.stop_instance","title":"aws ec2 stop-instances","summary":"Stop one instance. Public IP is released (use Elastic IP to retain).","description":"Stop one instance. Public IP is released (use Elastic IP to retain).","kind":"exec","risk":"high","side_effects":["Instance powers off; not billed for compute hours while stopped.","Public IPv4 address is lost unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Stop one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","stop-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.terminate_instance","title":"aws ec2 terminate-instances","summary":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","description":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","kind":"exec","risk":"critical","side_effects":["Instance is shutdown then DELETED.","All non-EBS storage (instance store) is lost.","EBS volumes with DeleteOnTermination=true are deleted too."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Terminate one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","terminate-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}}]},{"version":"0.1.4","content_hash":"sha256:8b3e27cb322c96c8d8e6883a57415c1460ac356d50b79ad634cae3cab181b350","tarball_url":"https://registry.emisar.dev/v1/packs/aws-ec2/0.1.4/8b3e27cb322c96c8d8e6883a57415c1460ac356d50b79ad634cae3cab181b350/pack.tar.gz","actions":[{"id":"ec2.console_output","title":"aws ec2 get-console-output","summary":"Get serial console output for one instance. Useful for boot diagnostics.","description":"Get serial console output for one instance. Useful for boot diagnostics.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Boot log","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","get-console-output","--instance-id","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instance_one","title":"aws ec2 describe-instances --instance-ids","summary":"Get details for one EC2 instance.","description":"Get details for one EC2 instance.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"i-xxxxxxxx[xxxxxxxxx]","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"One","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instances","title":"aws ec2 describe-instances","summary":"List all EC2 instances in the configured region with state + tags + IPs.","description":"List all EC2 instances in the configured region with state + tags + IPs.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All instances","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--output","json"]}},{"id":"ec2.describe_security_groups","title":"aws ec2 describe-security-groups","summary":"List all SGs with ingress/egress rules.","description":"List all SGs with ingress/egress rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All SGs","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-security-groups","--output","json"]}},{"id":"ec2.describe_subnets","title":"aws ec2 describe-subnets","summary":"List all subnets in this region.","description":"List all subnets in this region.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Subnets","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-subnets","--output","json"]}},{"id":"ec2.describe_volumes","title":"aws ec2 describe-volumes","summary":"List all EBS volumes with size + state + attachment.","description":"List all EBS volumes with size + state + attachment.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-volumes","--output","json"]}},{"id":"ec2.instance_status","title":"aws ec2 describe-instance-status","summary":"Show per-instance system + instance status checks.","description":"Show per-instance system + instance status checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Instance status checks","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instance-status","--include-all-instances","--output","json"]}},{"id":"ec2.reboot_instance","title":"aws ec2 reboot-instances","summary":"Reboot one instance. Instance keeps its IPs + ephemeral storage.","description":"Reboot one instance. Instance keeps its IPs + ephemeral storage.","kind":"exec","risk":"high","side_effects":["Instance reboots; ephemeral storage and IPs persist.","Brief downtime — services on host go down with it."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Reboot one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","reboot-instances","--instance-ids","{{ args.instance_id }}"]}},{"id":"ec2.start_instance","title":"aws ec2 start-instances","summary":"Start one stopped instance.","description":"Start one stopped instance.","kind":"exec","risk":"high","side_effects":["Instance begins booting; billing resumes.","New public IPv4 unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Start one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","start-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.stop_instance","title":"aws ec2 stop-instances","summary":"Stop one instance. Public IP is released (use Elastic IP to retain).","description":"Stop one instance. Public IP is released (use Elastic IP to retain).","kind":"exec","risk":"high","side_effects":["Instance powers off; not billed for compute hours while stopped.","Public IPv4 address is lost unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Stop one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","stop-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.terminate_instance","title":"aws ec2 terminate-instances","summary":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","description":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","kind":"exec","risk":"critical","side_effects":["Instance is shutdown then DELETED.","All non-EBS storage (instance store) is lost.","EBS volumes with DeleteOnTermination=true are deleted too."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Terminate one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","terminate-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}}]},{"version":"0.1.3","content_hash":"sha256:485aeeeb372b5f441b12d1b4419dfd00a094fcd1bb2091e7b6dd3ed19826179a","tarball_url":"https://registry.emisar.dev/v1/packs/aws-ec2/0.1.3/485aeeeb372b5f441b12d1b4419dfd00a094fcd1bb2091e7b6dd3ed19826179a/pack.tar.gz","actions":[{"id":"ec2.console_output","title":"aws ec2 get-console-output","summary":"Get serial console output for one instance. Useful for boot diagnostics.","description":"Get serial console output for one instance. Useful for boot diagnostics.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Boot log","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","get-console-output","--instance-id","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instance_one","title":"aws ec2 describe-instances --instance-ids","summary":"Get details for one EC2 instance.","description":"Get details for one EC2 instance.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"instance_id","type":"string","required":true,"description":"i-xxxxxxxx[xxxxxxxxx]","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"One","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.describe_instances","title":"aws ec2 describe-instances","summary":"List all EC2 instances in the configured region with state + tags + IPs.","description":"List all EC2 instances in the configured region with state + tags + IPs.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All instances","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instances","--output","json"]}},{"id":"ec2.describe_security_groups","title":"aws ec2 describe-security-groups","summary":"List all SGs with ingress/egress rules.","description":"List all SGs with ingress/egress rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All SGs","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-security-groups","--output","json"]}},{"id":"ec2.describe_subnets","title":"aws ec2 describe-subnets","summary":"List all subnets in this region.","description":"List all subnets in this region.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Subnets","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-subnets","--output","json"]}},{"id":"ec2.describe_volumes","title":"aws ec2 describe-volumes","summary":"List all EBS volumes with size + state + attachment.","description":"List all EBS volumes with size + state + attachment.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-volumes","--output","json"]}},{"id":"ec2.instance_status","title":"aws ec2 describe-instance-status","summary":"Show per-instance system + instance status checks.","description":"Show per-instance system + instance status checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Instance status checks","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","describe-instance-status","--include-all-instances","--output","json"]}},{"id":"ec2.reboot_instance","title":"aws ec2 reboot-instances","summary":"Reboots one instance. Instance keeps its IPs + ephemeral storage.","description":"Reboots one instance. Instance keeps its IPs + ephemeral storage.","kind":"exec","risk":"high","side_effects":["Instance reboots; ephemeral storage and IPs persist.","Brief downtime — services on host go down with it."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Reboot one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","reboot-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.start_instance","title":"aws ec2 start-instances","summary":"Starts one stopped instance.","description":"Starts one stopped instance.","kind":"exec","risk":"high","side_effects":["Instance begins booting; billing resumes.","New public IPv4 unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Start one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","start-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.stop_instance","title":"aws ec2 stop-instances","summary":"Stops one instance. Public IP is released (use Elastic IP to retain).","description":"Stops one instance. Public IP is released (use Elastic IP to retain).","kind":"exec","risk":"high","side_effects":["Instance powers off; not billed for compute hours while stopped.","Public IPv4 address is lost unless Elastic IP attached."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Stop one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","stop-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}},{"id":"ec2.terminate_instance","title":"aws ec2 terminate-instances","summary":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","description":"Permanently destroys one instance + its ephemeral storage. Cannot be undone.","kind":"exec","risk":"critical","side_effects":["Instance is shutdown then DELETED.","All non-EBS storage (instance store) is lost.","EBS volumes with DeleteOnTermination=true are deleted too."],"args":[{"name":"instance_id","type":"string","required":true,"description":"Instance ID.","validation":{"pattern":"^i-[0-9a-f]{8,17}$"}}],"examples":[{"title":"Terminate one","args":{"instance_id":"i-0123456789abcdef0"}}],"search_terms":[],"command":{"binary":"aws","argv":["ec2","terminate-instances","--instance-ids","{{ args.instance_id }}","--output","json"]}}]}]},{"id":"aws-iam","name":"AWS IAM operations","version":"0.1.8","description":"IAM introspection — users, roles, policies, attached policies, access keys — plus incident-response mutators: deactivate access key, delete access key, detach user policy. Auth via AWS_PROFILE. Routine IAM changes belong in IaC; these actions are for emergency lockout.","vendor":"emisar","homepage":"https://emisar.dev/packs/aws-iam","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/aws-iam","content_hash":"sha256:aee79c68e6cabde817ef13f336b21e09c05819af887629a8c13007e0ba2011be","tarball_url":"https://registry.emisar.dev/v1/packs/aws-iam/0.1.8/aee79c68e6cabde817ef13f336b21e09c05819af887629a8c13007e0ba2011be/pack.tar.gz","requires":{"os":["linux"],"binaries":["aws"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the aws CLI on the runner host. It resolves credentials from its own environment or `~/.aws` config — the runner only forwards the variables you allowlist in `inherit_env`.","env":[{"name":"AWS_PROFILE","description":"Named profile in `~/.aws/config` and `~/.aws/credentials`. Omit to use the default profile or static-key/instance-role auth.","example":"prod"},{"name":"AWS_ACCESS_KEY_ID","description":"Static access key. Use instead of a profile; pair with `AWS_SECRET_ACCESS_KEY`."},{"name":"AWS_SECRET_ACCESS_KEY","description":"Secret for `AWS_ACCESS_KEY_ID`."},{"name":"AWS_SESSION_TOKEN","description":"Session token for temporary (STS) credentials."}],"notes":["IAM is a global service, so no region is required (AWS_REGION is harmless if set).","Read actions need iam:Get*/List*. The mutators deactivate_access_key / delete_access_key / detach_user_policy additionally need iam:UpdateAccessKey / DeleteAccessKey / DetachUserPolicy.","Alternative to env keys: an `~/.aws/credentials` profile (read from disk, no `inherit_env` entry) or, on EC2/ECS, the instance/task role from instance metadata (no credentials needed at all)."],"verify":"iam.list_users"},"actions":[{"id":"iam.deactivate_access_key","title":"aws iam update-access-key --status Inactive","summary":"Disable an IAM access key. ALL API calls using this key fail immediately. Use during an incident when a key is suspected compromised — it stops blast radius before rotation completes. Reversible by setting status back to Active.","description":"Disable an IAM access key. ALL API calls using this key fail immediately. Use during an incident when a key is suspected compromised — it stops blast radius before rotation completes. Reversible by setting status back to Active.","kind":"exec","risk":"critical","side_effects":["All API calls with this key fail immediately.","Services using the key see auth errors until rotated.","Reversible (delete is not)."],"args":[{"name":"user_name","type":"string","required":true,"description":"IAM user name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,128}$"}},{"name":"access_key_id","type":"string","required":true,"description":"Access key ID (e.g., AKIA...).","validation":{"pattern":"^[A-Z0-9]{16,128}$"}}],"examples":[{"title":"Disable a leaked key","args":{"access_key_id":"AKIAEXAMPLE0000000000","user_name":"ci-bot"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","update-access-key","--user-name","{{ args.user_name }}","--access-key-id","{{ args.access_key_id }}","--status","Inactive"]}},{"id":"iam.delete_access_key","title":"aws iam delete-access-key","summary":"Permanently delete an IAM access key. Irreversible. Use after rotation when the old key is no longer needed. Prefer deactivate_access_key for incident response (it's reversible).","description":"Permanently delete an IAM access key. Irreversible. Use after rotation when the old key is no longer needed. Prefer deactivate_access_key for incident response (it's reversible).","kind":"exec","risk":"critical","side_effects":["Access key permanently gone.","Any service still using it gets a hard auth error.","Cannot be recovered."],"args":[{"name":"user_name","type":"string","required":true,"description":"IAM user name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,128}$"}},{"name":"access_key_id","type":"string","required":true,"description":"Access key ID.","validation":{"pattern":"^[A-Z0-9]{16,128}$"}}],"examples":[{"title":"Delete rotated key","args":{"access_key_id":"AKIAEXAMPLEOLDKEYID00","user_name":"ci-bot"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","delete-access-key","--user-name","{{ args.user_name }}","--access-key-id","{{ args.access_key_id }}"]}},{"id":"iam.detach_user_policy","title":"aws iam detach-user-policy","summary":"Detach one managed policy from one user. Use to remove overly broad permissions during an incident. The policy itself is not modified; just the attachment.","description":"Detach one managed policy from one user. Use to remove overly broad permissions during an incident. The policy itself is not modified; just the attachment.","kind":"exec","risk":"high","side_effects":["User loses the permissions that policy granted.","In-flight requests using those permissions begin failing.","Reversible by re-attaching."],"args":[{"name":"user_name","type":"string","required":true,"description":"IAM user name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,128}$"}},{"name":"policy_arn","type":"string","required":true,"description":"Policy ARN.","validation":{"pattern":"^arn:aws[a-zA-Z\\-]{0,14}:iam::(aws|[0-9]{12}):policy/[a-zA-Z0-9+=,.@\\-_/]{1,128}$"}}],"examples":[{"title":"Detach AdministratorAccess","args":{"policy_arn":"arn:aws:iam::aws:policy/AdministratorAccess","user_name":"intern"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","detach-user-policy","--user-name","{{ args.user_name }}","--policy-arn","{{ args.policy_arn }}"]}},{"id":"iam.get_role","title":"aws iam get-role","summary":"Get one IAM role's details + trust policy.","description":"Get one IAM role's details + trust policy.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"role","type":"string","required":true,"description":"Role name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"One role","args":{"role":"lambda-execution"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","get-role","--role-name","{{ args.role }}","--output","json"]}},{"id":"iam.get_user","title":"aws iam get-user","summary":"Get one IAM user's details.","description":"Get one IAM user's details.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"user","type":"string","required":true,"description":"Username.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"One user","args":{"user":"alice"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","get-user","--user-name","{{ args.user }}","--output","json"]}},{"id":"iam.last_used_access_key","title":"aws iam get-access-key-last-used","summary":"Show when one access key was last used (use to spot dormant keys).","description":"Show when one access key was last used (use to spot dormant keys).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"access_key_id","type":"string","required":true,"description":"AKIA…","validation":{"pattern":"^(AKIA|ASIA)[A-Z0-9]{16,30}$"}}],"examples":[{"title":"One key's last-used","args":{"access_key_id":"AKIAIOSFODNN7EXAMPLE"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","get-access-key-last-used","--access-key-id","{{ args.access_key_id }}","--output","json"]}},{"id":"iam.list_access_keys","title":"aws iam list-access-keys","summary":"List access key IDs for one user (NOT the secret).","description":"List access key IDs for one user (NOT the secret).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only — secret keys not returned."],"args":[{"name":"user","type":"string","required":true,"description":"Username.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"Access keys for one user","args":{"user":"alice"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-access-keys","--user-name","{{ args.user }}","--output","json"]}},{"id":"iam.list_attached_user_policies","title":"aws iam list-attached-user-policies","summary":"List policies attached to one IAM user.","description":"List policies attached to one IAM user.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"user","type":"string","required":true,"description":"Username.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"Attached policies","args":{"user":"alice"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-attached-user-policies","--user-name","{{ args.user }}","--output","json"]}},{"id":"iam.list_policies","title":"aws iam list-policies --scope Local","summary":"List all customer-managed IAM policies.","description":"List all customer-managed IAM policies.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Customer policies","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-policies","--scope","Local","--output","json"]}},{"id":"iam.list_roles","title":"aws iam list-roles","summary":"List all IAM roles in the account.","description":"List all IAM roles in the account.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All roles","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-roles","--output","json"]}},{"id":"iam.list_users","title":"aws iam list-users","summary":"List all IAM users in the account.","description":"List all IAM users in the account.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All users","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-users","--output","json"]}}],"previous_versions":[{"version":"0.1.5","content_hash":"sha256:62e9a24cf314ac855c8441a1e2002d39f9463904a14efa71bb97d8f6ab3f10eb","tarball_url":"https://registry.emisar.dev/v1/packs/aws-iam/0.1.5/62e9a24cf314ac855c8441a1e2002d39f9463904a14efa71bb97d8f6ab3f10eb/pack.tar.gz","actions":[{"id":"iam.deactivate_access_key","title":"aws iam update-access-key --status Inactive","summary":"Disable an IAM access key. ALL API calls using this key fail immediately. Use during an incident when a key is suspected compromised — it stops blast radius before rotation completes. Reversible by setting status back to Active.","description":"Disable an IAM access key. ALL API calls using this key fail immediately. Use during an incident when a key is suspected compromised — it stops blast radius before rotation completes. Reversible by setting status back to Active.","kind":"exec","risk":"critical","side_effects":["All API calls with this key fail immediately.","Services using the key see auth errors until rotated.","Reversible (delete is not)."],"args":[{"name":"user_name","type":"string","required":true,"description":"IAM user name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,128}$"}},{"name":"access_key_id","type":"string","required":true,"description":"Access key ID (e.g., AKIA...).","validation":{"pattern":"^[A-Z0-9]{16,128}$"}}],"examples":[{"title":"Disable a leaked key","args":{"access_key_id":"AKIAEXAMPLE0000000000","user_name":"ci-bot"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","update-access-key","--user-name","{{ args.user_name }}","--access-key-id","{{ args.access_key_id }}","--status","Inactive"]}},{"id":"iam.delete_access_key","title":"aws iam delete-access-key","summary":"Permanently delete an IAM access key. Irreversible. Use after rotation when the old key is no longer needed. Prefer deactivate_access_key for incident response (it's reversible).","description":"Permanently delete an IAM access key. Irreversible. Use after rotation when the old key is no longer needed. Prefer deactivate_access_key for incident response (it's reversible).","kind":"exec","risk":"critical","side_effects":["Access key permanently gone.","Any service still using it gets a hard auth error.","Cannot be recovered."],"args":[{"name":"user_name","type":"string","required":true,"description":"IAM user name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,128}$"}},{"name":"access_key_id","type":"string","required":true,"description":"Access key ID.","validation":{"pattern":"^[A-Z0-9]{16,128}$"}}],"examples":[{"title":"Delete rotated key","args":{"access_key_id":"AKIAEXAMPLEOLDKEYID00","user_name":"ci-bot"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","delete-access-key","--user-name","{{ args.user_name }}","--access-key-id","{{ args.access_key_id }}"]}},{"id":"iam.detach_user_policy","title":"aws iam detach-user-policy","summary":"Detach one managed policy from one user. Use to remove overly broad permissions during an incident. The policy itself is not modified; just the attachment.","description":"Detach one managed policy from one user. Use to remove overly broad permissions during an incident. The policy itself is not modified; just the attachment.","kind":"exec","risk":"high","side_effects":["User loses the permissions that policy granted.","In-flight requests using those permissions begin failing.","Reversible by re-attaching."],"args":[{"name":"user_name","type":"string","required":true,"description":"IAM user name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,128}$"}},{"name":"policy_arn","type":"string","required":true,"description":"Policy ARN.","validation":{"pattern":"^arn:aws[a-zA-Z\\-]{0,14}:iam::(aws|[0-9]{12}):policy/[a-zA-Z0-9+=,.@\\-_/]{1,128}$"}}],"examples":[{"title":"Detach AdministratorAccess","args":{"policy_arn":"arn:aws:iam::aws:policy/AdministratorAccess","user_name":"intern"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","detach-user-policy","--user-name","{{ args.user_name }}","--policy-arn","{{ args.policy_arn }}"]}},{"id":"iam.get_role","title":"aws iam get-role","summary":"Get one IAM role's details + trust policy.","description":"Get one IAM role's details + trust policy.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"role","type":"string","required":true,"description":"Role name.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"One role","args":{"role":"lambda-execution"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","get-role","--role-name","{{ args.role }}","--output","json"]}},{"id":"iam.get_user","title":"aws iam get-user","summary":"Get one IAM user's details.","description":"Get one IAM user's details.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"user","type":"string","required":true,"description":"Username.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"One user","args":{"user":"alice"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","get-user","--user-name","{{ args.user }}","--output","json"]}},{"id":"iam.last_used_access_key","title":"aws iam get-access-key-last-used","summary":"Show when one access key was last used (use to spot dormant keys).","description":"Show when one access key was last used (use to spot dormant keys).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"access_key_id","type":"string","required":true,"description":"AKIA…","validation":{"pattern":"^(AKIA|ASIA)[A-Z0-9]{16,30}$"}}],"examples":[{"title":"One key's last-used","args":{"access_key_id":"AKIAIOSFODNN7EXAMPLE"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","get-access-key-last-used","--access-key-id","{{ args.access_key_id }}","--output","json"]}},{"id":"iam.list_access_keys","title":"aws iam list-access-keys","summary":"List access key IDs for one user (NOT the secret).","description":"List access key IDs for one user (NOT the secret).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only — secret keys not returned."],"args":[{"name":"user","type":"string","required":true,"description":"Username.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"Access keys for one user","args":{"user":"alice"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-access-keys","--user-name","{{ args.user }}","--output","json"]}},{"id":"iam.list_attached_user_policies","title":"aws iam list-attached-user-policies","summary":"List policies attached to one IAM user.","description":"List policies attached to one IAM user.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"user","type":"string","required":true,"description":"Username.","validation":{"pattern":"^[a-zA-Z0-9_+=,.@\\-]{1,64}$"}}],"examples":[{"title":"Attached policies","args":{"user":"alice"}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-attached-user-policies","--user-name","{{ args.user }}","--output","json"]}},{"id":"iam.list_policies","title":"aws iam list-policies --scope Local","summary":"List all customer-managed IAM policies.","description":"List all customer-managed IAM policies.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Customer policies","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-policies","--scope","Local","--output","json"]}},{"id":"iam.list_roles","title":"aws iam list-roles","summary":"List all IAM roles in the account.","description":"List all IAM roles in the account.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All roles","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-roles","--output","json"]}},{"id":"iam.list_users","title":"aws iam list-users","summary":"List all IAM users in the account.","description":"List all IAM users in the account.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All users","args":{}}],"search_terms":[],"command":{"binary":"aws","argv":["iam","list-users","--output","json"]}}]}]},{"id":"aws-rds","name":"AWS RDS operations","version":"0.1.9","description":"Read-only RDS diagnostics for bounded instance, cluster, snapshot, parameter-group, pending-maintenance, and recent-event inventory. Responses are projected to operational fields and omit tags and arbitrary descriptions. Auth via AWS_PROFILE.","vendor":"emisar","homepage":"https://emisar.dev/packs/aws-rds","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/aws-rds","content_hash":"sha256:ab5218b5f76e06fc5bb764ed045b86331e4bd11ef21948b18c036988bcad5e98","tarball_url":"https://registry.emisar.dev/v1/packs/aws-rds/0.1.9/ab5218b5f76e06fc5bb764ed045b86331e4bd11ef21948b18c036988bcad5e98/pack.tar.gz","requires":{"os":["linux"],"binaries":["aws","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the aws CLI on the runner host. It resolves credentials and region from its own environment or `~/.aws` config — the runner only forwards the variables you allowlist in `inherit_env`.","env":[{"name":"AWS_PROFILE","description":"Named profile in `~/.aws/config` and `~/.aws/credentials`. Omit to use the default profile or static-key/instance-role auth.","example":"prod"},{"name":"AWS_REGION","required":true,"description":"Region to operate in; RDS is regional, so calls fail without it.","example":"us-east-1"},{"name":"AWS_ACCESS_KEY_ID","description":"Static access key. Use instead of a profile; pair with `AWS_SECRET_ACCESS_KEY`."},{"name":"AWS_SECRET_ACCESS_KEY","description":"Secret for `AWS_ACCESS_KEY_ID`."},{"name":"AWS_SESSION_TOKEN","description":"Session token for temporary (STS) credentials."}],"notes":["An EC2 instance role or ECS task role needs no key at all and is the shape to prefer; a static pair is minted from [the IAM users console](https://console.aws.amazon.com/iam/home#/users) → the user → Security credentials → Create access key.","Actions need only the corresponding rds:Describe* permissions and never mutate RDS resources.","Alternative to env keys: an `~/.aws/credentials` profile (read from disk, no `inherit_env` entry) or, on EC2/ECS, the instance/task role from instance metadata (no credentials needed at all).","List actions return a `next_page_cursor`; feed it back as `page_cursor` for explicit bounded pagination.","This remote-target pack declares no host detection signal and is never auto-suggested merely because aws is installed."],"verify":"rds.list_instances"},"actions":[{"id":"rds.cluster_parameter_groups","title":"aws rds describe-db-cluster-parameter-groups","summary":"List a bounded page of cluster parameter-group names, families, and ARNs without arbitrary descriptions.","description":"List a bounded page of cluster parameter-group names, families, and ARNs without arbitrary descriptions.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum parameter groups to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Aurora parameter groups","args":{}}],"search_terms":[]},{"id":"rds.describe_cluster","title":"aws rds describe-db-clusters --db-cluster-identifier","summary":"Show one Aurora or Multi-AZ cluster's members, endpoints, backup, network, and encryption state.","description":"Show one Aurora or Multi-AZ cluster's members, endpoints, backup, network, and encryption state.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"cluster","type":"string","required":true,"description":"Cluster identifier.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9\\-]{0,62}$"}}],"examples":[{"title":"One cluster","args":{"cluster":"prod-aurora"}}],"search_terms":[]},{"id":"rds.describe_instance","title":"aws rds describe-db-instances --db-instance-identifier","summary":"Show one RDS instance's availability, network, storage, backup, maintenance, and encryption state.","description":"Show one RDS instance's availability, network, storage, backup, maintenance, and encryption state.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"instance","type":"string","required":true,"description":"Instance identifier.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9\\-]{0,62}$"}}],"examples":[{"title":"One instance","args":{"instance":"prod-postgres-1"}}],"search_terms":[]},{"id":"rds.list_cluster_snapshots","title":"aws rds describe-db-cluster-snapshots","summary":"List a bounded page of RDS cluster snapshots with source, status, engine, capacity, and encryption state.","description":"List a bounded page of RDS cluster snapshots with source, status, engine, capacity, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Cluster snapshots","args":{}}],"search_terms":[]},{"id":"rds.list_clusters","title":"aws rds describe-db-clusters","summary":"List a bounded page of Aurora and Multi-AZ clusters with members, endpoints, backup, network, and encryption state.","description":"List a bounded page of Aurora and Multi-AZ clusters with members, endpoints, backup, network, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum clusters to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Aurora clusters","args":{}}],"search_terms":[]},{"id":"rds.list_instances","title":"aws rds describe-db-instances","summary":"List a bounded page of RDS instances with availability, network, storage, backup, maintenance, and encryption state.","description":"List a bounded page of RDS instances with availability, network, storage, backup, maintenance, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum instances to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"All instances","args":{}}],"search_terms":[]},{"id":"rds.list_snapshots","title":"aws rds describe-db-snapshots","summary":"List a bounded page of RDS instance snapshots with source, status, engine, capacity, and encryption state.","description":"List a bounded page of RDS instance snapshots with source, status, engine, capacity, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[]},{"id":"rds.parameter_groups","title":"aws rds describe-db-parameter-groups","summary":"List a bounded page of instance parameter-group names, families, and ARNs without arbitrary descriptions.","description":"List a bounded page of instance parameter-group names, families, and ARNs without arbitrary descriptions.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum parameter groups to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Parameter groups","args":{}}],"search_terms":[]},{"id":"rds.pending_maintenance","title":"aws rds describe-pending-maintenance-actions","summary":"List a bounded page of pending RDS maintenance with automatic, forced, and current apply dates.","description":"List a bounded page of pending RDS maintenance with automatic, forced, and current apply dates.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum resources to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Pending maintenance","args":{}}],"search_terms":[]},{"id":"rds.recent_events","title":"aws rds describe-events","summary":"List a bounded page of recent RDS events across instances, clusters, snapshots, and parameter groups.","description":"List a bounded page of recent RDS events across instances, clusters, snapshots, and parameter groups.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"duration_minutes","type":"integer","required":false,"default":60,"description":"Lookback window in minutes.","validation":{"min":1,"max":1440}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum events to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque AWS CLI pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Last two hours","args":{"duration_minutes":120}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.8","content_hash":"sha256:16925e0535a06bb63003216bbfcd058d55a1799ff192d5b8811c38c30da9d64c","tarball_url":"https://registry.emisar.dev/v1/packs/aws-rds/0.1.8/16925e0535a06bb63003216bbfcd058d55a1799ff192d5b8811c38c30da9d64c/pack.tar.gz","actions":[{"id":"rds.cluster_parameter_groups","title":"aws rds describe-db-cluster-parameter-groups","summary":"List a bounded page of cluster parameter-group names, families, and ARNs without arbitrary descriptions.","description":"List a bounded page of cluster parameter-group names, families, and ARNs without arbitrary descriptions.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum parameter groups to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Aurora parameter groups","args":{}}],"search_terms":[]},{"id":"rds.describe_cluster","title":"aws rds describe-db-clusters --db-cluster-identifier","summary":"Show one Aurora or Multi-AZ cluster's members, endpoints, backup, network, and encryption state.","description":"Show one Aurora or Multi-AZ cluster's members, endpoints, backup, network, and encryption state.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"cluster","type":"string","required":true,"description":"Cluster identifier.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9\\-]{0,62}$"}}],"examples":[{"title":"One cluster","args":{"cluster":"prod-aurora"}}],"search_terms":[]},{"id":"rds.describe_instance","title":"aws rds describe-db-instances --db-instance-identifier","summary":"Show one RDS instance's availability, network, storage, backup, maintenance, and encryption state.","description":"Show one RDS instance's availability, network, storage, backup, maintenance, and encryption state.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"instance","type":"string","required":true,"description":"Instance identifier.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9\\-]{0,62}$"}}],"examples":[{"title":"One instance","args":{"instance":"prod-postgres-1"}}],"search_terms":[]},{"id":"rds.list_cluster_snapshots","title":"aws rds describe-db-cluster-snapshots","summary":"List a bounded page of RDS cluster snapshots with source, status, engine, capacity, and encryption state.","description":"List a bounded page of RDS cluster snapshots with source, status, engine, capacity, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Cluster snapshots","args":{}}],"search_terms":[]},{"id":"rds.list_clusters","title":"aws rds describe-db-clusters","summary":"List a bounded page of Aurora and Multi-AZ clusters with members, endpoints, backup, network, and encryption state.","description":"List a bounded page of Aurora and Multi-AZ clusters with members, endpoints, backup, network, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum clusters to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Aurora clusters","args":{}}],"search_terms":[]},{"id":"rds.list_instances","title":"aws rds describe-db-instances","summary":"List a bounded page of RDS instances with availability, network, storage, backup, maintenance, and encryption state.","description":"List a bounded page of RDS instances with availability, network, storage, backup, maintenance, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum instances to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"All instances","args":{}}],"search_terms":[]},{"id":"rds.list_snapshots","title":"aws rds describe-db-snapshots","summary":"List a bounded page of RDS instance snapshots with source, status, engine, capacity, and encryption state.","description":"List a bounded page of RDS instance snapshots with source, status, engine, capacity, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[]},{"id":"rds.parameter_groups","title":"aws rds describe-db-parameter-groups","summary":"List a bounded page of instance parameter-group names, families, and ARNs without arbitrary descriptions.","description":"List a bounded page of instance parameter-group names, families, and ARNs without arbitrary descriptions.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum parameter groups to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Parameter groups","args":{}}],"search_terms":[]},{"id":"rds.pending_maintenance","title":"aws rds describe-pending-maintenance-actions","summary":"List a bounded page of pending RDS maintenance with automatic, forced, and current apply dates.","description":"List a bounded page of pending RDS maintenance with automatic, forced, and current apply dates.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum resources to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Pending maintenance","args":{}}],"search_terms":[]},{"id":"rds.recent_events","title":"aws rds describe-events","summary":"List a bounded page of recent RDS events across instances, clusters, snapshots, and parameter groups.","description":"List a bounded page of recent RDS events across instances, clusters, snapshots, and parameter groups.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"duration_minutes","type":"integer","required":false,"default":60,"description":"Lookback window in minutes.","validation":{"min":1,"max":1440}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum events to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Last two hours","args":{"duration_minutes":120}}],"search_terms":[]}]},{"version":"0.1.3","content_hash":"sha256:2efa7934d7170d37c6379867d2520d0361942d4e0847ea621bb82a6518dad993","tarball_url":"https://registry.emisar.dev/v1/packs/aws-rds/0.1.3/2efa7934d7170d37c6379867d2520d0361942d4e0847ea621bb82a6518dad993/pack.tar.gz","actions":[{"id":"rds.cluster_parameter_groups","title":"aws rds describe-db-cluster-parameter-groups","summary":"List a bounded page of cluster parameter-group names, families, and ARNs without arbitrary descriptions.","description":"List a bounded page of cluster parameter-group names, families, and ARNs without arbitrary descriptions.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum parameter groups to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Aurora parameter groups","args":{}}],"search_terms":[]},{"id":"rds.describe_cluster","title":"aws rds describe-db-clusters --db-cluster-identifier","summary":"Show one Aurora or Multi-AZ cluster's members, endpoints, backup, network, and encryption state.","description":"Show one Aurora or Multi-AZ cluster's members, endpoints, backup, network, and encryption state.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"cluster","type":"string","required":true,"description":"Cluster identifier.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9\\-]{0,62}$"}}],"examples":[{"title":"One cluster","args":{"cluster":"prod-aurora"}}],"search_terms":[]},{"id":"rds.describe_instance","title":"aws rds describe-db-instances --db-instance-identifier","summary":"Show one RDS instance's availability, network, storage, backup, maintenance, and encryption state.","description":"Show one RDS instance's availability, network, storage, backup, maintenance, and encryption state.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"instance","type":"string","required":true,"description":"Instance identifier.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9\\-]{0,62}$"}}],"examples":[{"title":"One instance","args":{"instance":"prod-postgres-1"}}],"search_terms":[]},{"id":"rds.list_cluster_snapshots","title":"aws rds describe-db-cluster-snapshots","summary":"List a bounded page of RDS cluster snapshots with source, status, engine, capacity, and encryption state.","description":"List a bounded page of RDS cluster snapshots with source, status, engine, capacity, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Cluster snapshots","args":{}}],"search_terms":[]},{"id":"rds.list_clusters","title":"aws rds describe-db-clusters","summary":"List a bounded page of Aurora and Multi-AZ clusters with members, endpoints, backup, network, and encryption state.","description":"List a bounded page of Aurora and Multi-AZ clusters with members, endpoints, backup, network, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum clusters to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Aurora clusters","args":{}}],"search_terms":[]},{"id":"rds.list_instances","title":"aws rds describe-db-instances","summary":"List a bounded page of RDS instances with availability, network, storage, backup, maintenance, and encryption state.","description":"List a bounded page of RDS instances with availability, network, storage, backup, maintenance, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum instances to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"All instances","args":{}}],"search_terms":[]},{"id":"rds.list_snapshots","title":"aws rds describe-db-snapshots","summary":"List a bounded page of RDS instance snapshots with source, status, engine, capacity, and encryption state.","description":"List a bounded page of RDS instance snapshots with source, status, engine, capacity, and encryption state.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[]},{"id":"rds.parameter_groups","title":"aws rds describe-db-parameter-groups","summary":"List a bounded page of instance parameter-group names, families, and ARNs without arbitrary descriptions.","description":"List a bounded page of instance parameter-group names, families, and ARNs without arbitrary descriptions.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum parameter groups to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Parameter groups","args":{}}],"search_terms":[]},{"id":"rds.pending_maintenance","title":"aws rds describe-pending-maintenance-actions","summary":"List a bounded page of pending RDS maintenance with automatic, forced, and current apply dates.","description":"List a bounded page of pending RDS maintenance with automatic, forced, and current apply dates.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum resources to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Pending maintenance","args":{}}],"search_terms":[]},{"id":"rds.recent_events","title":"aws rds describe-events","summary":"List a bounded page of recent RDS events across instances, clusters, snapshots, and parameter groups.","description":"List a bounded page of recent RDS events across instances, clusters, snapshots, and parameter groups.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"duration_minutes","type":"integer","required":false,"default":60,"description":"Lookback window in minutes.","validation":{"min":1,"max":1440}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum events to return.","validation":{"min":1,"max":1000}},{"name":"next_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque AWS CLI token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Last two hours","args":{"duration_minutes":120}}],"search_terms":[]}]}],"retired_below":"0.1.3"},{"id":"aws-s3","name":"AWS S3 operations","version":"0.1.8","description":"Read-only S3 diagnostics for bounded bucket and object inventory, access, ownership, policy, logging, replication, lifecycle, encryption, versioning, and fixed object metadata. Object bodies and custom metadata values are excluded. Auth via AWS_PROFILE.","vendor":"emisar","homepage":"https://emisar.dev/packs/aws-s3","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/aws-s3","content_hash":"sha256:d4d420521c1843328af46ed1ffe2c478953205913826f3229ee03e2ba7c0cf1e","tarball_url":"https://registry.emisar.dev/v1/packs/aws-s3/0.1.8/d4d420521c1843328af46ed1ffe2c478953205913826f3229ee03e2ba7c0cf1e/pack.tar.gz","requires":{"os":["linux"],"binaries":["aws","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the aws CLI on the runner host. It resolves credentials from its own environment or `~/.aws` config — the runner only forwards the variables you allowlist in `inherit_env`.","env":[{"name":"AWS_PROFILE","description":"Named profile in `~/.aws/config` and `~/.aws/credentials`. Omit to use the default profile or static-key/instance-role auth.","example":"prod"},{"name":"AWS_REGION","description":"Default region for the CLI. S3 redirects per-bucket calls to the bucket's own region, so this is rarely required; set it to avoid an unset-region error on some setups.","example":"us-east-1"},{"name":"AWS_ACCESS_KEY_ID","description":"Static access key. Use instead of a profile; pair with `AWS_SECRET_ACCESS_KEY`."},{"name":"AWS_SECRET_ACCESS_KEY","description":"Secret for `AWS_ACCESS_KEY_ID`."},{"name":"AWS_SESSION_TOKEN","description":"Session token for temporary (STS) credentials."}],"notes":["Read-only: the principal needs s3:ListAllMyBuckets, s3:ListBucket, s3:GetBucketLocation and the exact s3:GetBucket* / s3:GetObject permissions for the buckets you inspect.","Alternative to env keys: an `~/.aws/credentials` profile (read from disk, no `inherit_env` entry) or, on EC2/ECS, the instance/task role from instance metadata (no credentials needed at all).","Object metadata is projected locally: custom metadata key names are returned, but their values and object bodies never leave the runner.","List actions return a `next_page_cursor`; feed it back as `page_cursor` for explicit bounded pagination.","This remote-target pack declares no host detection signal and is never auto-suggested merely because aws is installed."],"verify":"s3.list_buckets"},"actions":[{"id":"s3.bucket_encryption","title":"aws s3api get-bucket-encryption","summary":"Show default-encryption settings for one bucket.","description":"Show default-encryption settings for one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Encryption","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-encryption","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_lifecycle","title":"aws s3api get-bucket-lifecycle-configuration","summary":"Show lifecycle rules (auto-expiry, glacier transition).","description":"Show lifecycle rules (auto-expiry, glacier transition).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Lifecycle","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-lifecycle-configuration","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_location","title":"aws s3api get-bucket-location","summary":"Show the region for one bucket.","description":"Show the region for one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Region","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-location","--bucket","{{ args.bucket }}"]}},{"id":"s3.bucket_logging","title":"aws s3api get-bucket-logging","summary":"Show one bucket's server access logging destination and grants.","description":"Show one bucket's server access logging destination and grants.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Access logging","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-logging","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_ownership","title":"aws s3api get-bucket-ownership-controls","summary":"Show one bucket's object ownership controls.","description":"Show one bucket's object ownership controls.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Object ownership","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-ownership-controls","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_policy","title":"aws s3api get-bucket-policy","summary":"Show bucket policy JSON.","description":"Show bucket policy JSON.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Policy","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-policy","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_policy_status","title":"aws s3api get-bucket-policy-status","summary":"Show whether one bucket policy makes the bucket public.","description":"Show whether one bucket policy makes the bucket public.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Policy public status","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-policy-status","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_public_access","title":"aws s3api get-public-access-block","summary":"Show one bucket's public-access block controls.","description":"Show one bucket's public-access block controls.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Public access controls","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-public-access-block","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_replication","title":"aws s3api get-bucket-replication","summary":"Show one bucket's replication role and rules.","description":"Show one bucket's replication role and rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Replication","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-replication","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_versioning","title":"aws s3api get-bucket-versioning","summary":"Show versioning state of one bucket.","description":"Show versioning state of one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Versioning","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-versioning","--bucket","{{ args.bucket }}"]}},{"id":"s3.list_buckets","title":"aws s3api list-buckets","summary":"List a bounded page of buckets the active AWS identity can access.","description":"List a bounded page of buckets the active AWS identity can access.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum buckets to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque service pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"All buckets","args":{}}],"search_terms":[]},{"id":"s3.list_objects","title":"aws s3api list-objects-v2","summary":"List one bounded page of object system metadata under a literal prefix.","description":"List one bounded page of object system metadata under a literal prefix.","kind":"script","risk":"low","side_effects":["One ListObjectsV2 call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}},{"name":"prefix","type":"string","required":false,"default":"","description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.!*'(),/\\-]{0,512}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum objects to return.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque service pagination cursor from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Objects under prefix","args":{"bucket":"my-bucket","prefix":"logs/2026/"}}],"search_terms":[]},{"id":"s3.object_metadata","title":"aws s3api head-object","summary":"Show one object's system metadata and custom metadata keys without its body or custom values.","description":"Show one object's system metadata and custom metadata keys without its body or custom values.","kind":"script","risk":"low","side_effects":["One HeadObject call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}},{"name":"key","type":"string","required":true,"description":"Object key.","validation":{"pattern":"^[a-zA-Z0-9_.!*'(),/\\-]{1,1000}[a-zA-Z0-9_.!*'(),/\\-]{0,24}$"}}],"examples":[{"title":"One object","args":{"bucket":"my-bucket","key":"logs/2026/06/01.log"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.7","content_hash":"sha256:c89358429df2fafe79852c6eb5199b36fa00f00a139a155247da0e840caddb05","tarball_url":"https://registry.emisar.dev/v1/packs/aws-s3/0.1.7/c89358429df2fafe79852c6eb5199b36fa00f00a139a155247da0e840caddb05/pack.tar.gz","actions":[{"id":"s3.bucket_encryption","title":"aws s3api get-bucket-encryption","summary":"Show default-encryption settings for one bucket.","description":"Show default-encryption settings for one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Encryption","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-encryption","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_lifecycle","title":"aws s3api get-bucket-lifecycle-configuration","summary":"Show lifecycle rules (auto-expiry, glacier transition).","description":"Show lifecycle rules (auto-expiry, glacier transition).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Lifecycle","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-lifecycle-configuration","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_location","title":"aws s3api get-bucket-location","summary":"Show the region for one bucket.","description":"Show the region for one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Region","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-location","--bucket","{{ args.bucket }}"]}},{"id":"s3.bucket_logging","title":"aws s3api get-bucket-logging","summary":"Show one bucket's server access logging destination and grants.","description":"Show one bucket's server access logging destination and grants.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Access logging","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-logging","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_ownership","title":"aws s3api get-bucket-ownership-controls","summary":"Show one bucket's object ownership controls.","description":"Show one bucket's object ownership controls.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Object ownership","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-ownership-controls","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_policy","title":"aws s3api get-bucket-policy","summary":"Show bucket policy JSON.","description":"Show bucket policy JSON.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Policy","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-policy","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_policy_status","title":"aws s3api get-bucket-policy-status","summary":"Show whether one bucket policy makes the bucket public.","description":"Show whether one bucket policy makes the bucket public.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Policy public status","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-policy-status","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_public_access","title":"aws s3api get-public-access-block","summary":"Show one bucket's public-access block controls.","description":"Show one bucket's public-access block controls.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Public access controls","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-public-access-block","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_replication","title":"aws s3api get-bucket-replication","summary":"Show one bucket's replication role and rules.","description":"Show one bucket's replication role and rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Replication","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-replication","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_versioning","title":"aws s3api get-bucket-versioning","summary":"Show versioning state of one bucket.","description":"Show versioning state of one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Versioning","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-versioning","--bucket","{{ args.bucket }}"]}},{"id":"s3.list_buckets","title":"aws s3api list-buckets","summary":"List a bounded page of buckets the active AWS identity can access.","description":"List a bounded page of buckets the active AWS identity can access.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum buckets to return.","validation":{"min":1,"max":1000}},{"name":"continuation_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque service continuation token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"All buckets","args":{}}],"search_terms":[]},{"id":"s3.list_objects","title":"aws s3api list-objects-v2","summary":"List one bounded page of object system metadata under a literal prefix.","description":"List one bounded page of object system metadata under a literal prefix.","kind":"script","risk":"low","side_effects":["One ListObjectsV2 call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}},{"name":"prefix","type":"string","required":false,"default":"","description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.!*'(),/\\-]{0,512}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum objects to return.","validation":{"min":1,"max":1000}},{"name":"continuation_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque service continuation token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Objects under prefix","args":{"bucket":"my-bucket","prefix":"logs/2026/"}}],"search_terms":[]},{"id":"s3.object_metadata","title":"aws s3api head-object","summary":"Show one object's system metadata and custom metadata keys without its body or custom values.","description":"Show one object's system metadata and custom metadata keys without its body or custom values.","kind":"script","risk":"low","side_effects":["One HeadObject call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}},{"name":"key","type":"string","required":true,"description":"Object key.","validation":{"pattern":"^[a-zA-Z0-9_.!*'(),/\\-]{1,1000}[a-zA-Z0-9_.!*'(),/\\-]{0,24}$"}}],"examples":[{"title":"One object","args":{"bucket":"my-bucket","key":"logs/2026/06/01.log"}}],"search_terms":[]}]},{"version":"0.1.4","content_hash":"sha256:39ed6b22f6331f0c83eb554efea893751affb16e1419989159f7e29498165ac7","tarball_url":"https://registry.emisar.dev/v1/packs/aws-s3/0.1.4/39ed6b22f6331f0c83eb554efea893751affb16e1419989159f7e29498165ac7/pack.tar.gz","actions":[{"id":"s3.bucket_encryption","title":"aws s3api get-bucket-encryption","summary":"Show default-encryption settings for one bucket.","description":"Show default-encryption settings for one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Encryption","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-encryption","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_lifecycle","title":"aws s3api get-bucket-lifecycle-configuration","summary":"Show lifecycle rules (auto-expiry, glacier transition).","description":"Show lifecycle rules (auto-expiry, glacier transition).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Lifecycle","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-lifecycle-configuration","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_location","title":"aws s3api get-bucket-location","summary":"Show the region for one bucket.","description":"Show the region for one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Region","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-location","--bucket","{{ args.bucket }}"]}},{"id":"s3.bucket_logging","title":"aws s3api get-bucket-logging","summary":"Show one bucket's server access logging destination and grants.","description":"Show one bucket's server access logging destination and grants.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Access logging","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-logging","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_ownership","title":"aws s3api get-bucket-ownership-controls","summary":"Show one bucket's object ownership controls.","description":"Show one bucket's object ownership controls.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Object ownership","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-ownership-controls","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_policy","title":"aws s3api get-bucket-policy","summary":"Show bucket policy JSON.","description":"Show bucket policy JSON.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Policy","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-policy","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_policy_status","title":"aws s3api get-bucket-policy-status","summary":"Show whether one bucket policy makes the bucket public.","description":"Show whether one bucket policy makes the bucket public.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Policy public status","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-policy-status","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_public_access","title":"aws s3api get-public-access-block","summary":"Show one bucket's public-access block controls.","description":"Show one bucket's public-access block controls.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Public access controls","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-public-access-block","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_replication","title":"aws s3api get-bucket-replication","summary":"Show one bucket's replication role and rules.","description":"Show one bucket's replication role and rules.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Replication","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-replication","--bucket","{{ args.bucket }}","--output","json"]}},{"id":"s3.bucket_versioning","title":"aws s3api get-bucket-versioning","summary":"Show versioning state of one bucket.","description":"Show versioning state of one bucket.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Versioning","args":{"bucket":"my-bucket"}}],"search_terms":[],"command":{"binary":"aws","argv":["s3api","get-bucket-versioning","--bucket","{{ args.bucket }}"]}},{"id":"s3.list_buckets","title":"aws s3api list-buckets","summary":"List a bounded page of buckets the active AWS identity can access.","description":"List a bounded page of buckets the active AWS identity can access.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum buckets to return.","validation":{"min":1,"max":1000}},{"name":"continuation_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque service continuation token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"All buckets","args":{}}],"search_terms":[]},{"id":"s3.list_objects","title":"aws s3api list-objects-v2","summary":"List one bounded page of object system metadata under a literal prefix.","description":"List one bounded page of object system metadata under a literal prefix.","kind":"script","risk":"low","side_effects":["One ListObjectsV2 call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}},{"name":"prefix","type":"string","required":false,"default":"","description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.!*'(),/\\-]{0,512}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum objects to return.","validation":{"min":1,"max":1000}},{"name":"continuation_token","type":"string","required":false,"sensitive":true,"default":"","description":"Opaque service continuation token from a previous result.","validation":{"pattern":"^[A-Za-z0-9+/=_-]*$","max_length":4096}}],"examples":[{"title":"Objects under prefix","args":{"bucket":"my-bucket","prefix":"logs/2026/"}}],"search_terms":[]},{"id":"s3.object_metadata","title":"aws s3api head-object","summary":"Show one object's system metadata and custom metadata keys without its body or custom values.","description":"Show one object's system metadata and custom metadata keys without its body or custom values.","kind":"script","risk":"low","side_effects":["One HeadObject call.","Read-only.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}},{"name":"key","type":"string","required":true,"description":"Object key.","validation":{"pattern":"^[a-zA-Z0-9_.!*'(),/\\-]{1,1000}[a-zA-Z0-9_.!*'(),/\\-]{0,24}$"}}],"examples":[{"title":"One object","args":{"bucket":"my-bucket","key":"logs/2026/06/01.log"}}],"search_terms":[]}]}],"retired_below":"0.1.4"},{"id":"bind","name":"BIND DNS server","version":"0.1.16","description":"Authoritative/recursive BIND ops: rndc status + stats, zone validation, cache inspection, local resolution probes, plus narrow operator actions (rndc reload, zone freeze/thaw). Requires rndc key on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/bind","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/bind","content_hash":"sha256:6c322e1349349ecef6f36e55809d179bee141a94c9d9b4de33cf710e8f2d24dd","tarball_url":"https://registry.emisar.dev/v1/packs/bind/0.1.16/6c322e1349349ecef6f36e55809d179bee141a94c9d9b4de33cf710e8f2d24dd/pack.tar.gz","requires":{"os":["linux"],"binaries":["rndc"]},"detect":{"binaries":[],"processes":["named"],"ports":[]},"setup":{"summary":"Operates on the local named instance on the runner host — no credentials needed. rndc controls named via its key file; dig queries 127.0.0.1.","notes":["zone_dump (AXFR) requires named's allow-transfer to include 127.0.0.1."],"host_access":[{"actions":["bind.rndc_status","bind.rndc_stats","bind.named_checkconf","bind.named_checkzone","bind.rndc_reload","bind.rndc_freeze","bind.rndc_thaw","bind.rndc_flush"],"requirement":"Read BIND's protected configuration and RNDC key and control the local named process.","recipes":[{"name":"Add the default Emisar service user to bind on Debian or Ubuntu","commands":["sudo usermod -aG bind emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx bind","sudo -u emisar rndc status >/dev/null","sudo -u emisar named-checkconf"],"impact":"Every process running as emisar can read files exposed to the bind group and use the RNDC key to mutate named beyond the actions exposed by this pack."},{"name":"Add the default Emisar service user to named on RHEL-family hosts","commands":["sudo usermod -aG named emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx named","sudo -u emisar rndc status >/dev/null","sudo -u emisar named-checkconf"],"impact":"Every process running as emisar can read files exposed to the named group and use the RNDC key to mutate named beyond the actions exposed by this pack."}]}],"verify":"bind.rndc_status"},"actions":[{"id":"bind.named_checkconf","title":"named-checkconf","summary":"Validate named.conf syntax. Run before any rndc reload.","description":"Validate named.conf syntax. Run before any rndc reload.","kind":"exec","risk":"low","side_effects":["Reads named.conf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"named-checkconf","argv":[]}},{"id":"bind.named_checkzone","title":"named-checkzone <zone> <file>","summary":"Validate one zone file.","description":"Validate one zone file.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"file","type":"string","required":true,"description":"Zone file path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/bind","/var/lib/bind","/var/named","/etc/named"]}}],"examples":[{"title":"Check zone file","args":{"file":"/etc/bind/db.example.com","zone":"example.com"}}],"search_terms":[],"command":{"binary":"named-checkzone","argv":["{{ args.zone }}","{{ args.file }}"]}},{"id":"bind.query_local","title":"dig @localhost <name> <type>","summary":"Resolve one name against the local named.","description":"Resolve one name against the local named.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Name to query.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SOA","PTR","SRV","CAA","ANY"]}}],"examples":[{"title":"Local lookup","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.name }}","{{ args.type }}","+short"]}},{"id":"bind.rndc_flush","title":"rndc flush","summary":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","description":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","kind":"exec","risk":"medium","side_effects":["Resolver cache is emptied.","Brief upstream-query spike as cache repopulates."],"args":[],"examples":[{"title":"Flush all caches","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["flush"]}},{"id":"bind.rndc_freeze","title":"rndc freeze <zone>","summary":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","description":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","kind":"exec","risk":"medium","side_effects":["Dynamic-update writes paused for the zone.","Reverse with rndc thaw."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Freeze before edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["freeze","{{ args.zone }}"]}},{"id":"bind.rndc_reload","title":"rndc reload [zone]","summary":"Reload named config (or one zone). Validates first if zone specified.","description":"Reload named config (or one zone). Validates first if zone specified.","kind":"exec","risk":"high","side_effects":["Brief lock on the zone(s) being reloaded.","Invalid config aborts the reload; old data stays in place."],"args":[{"name":"zone","type":"string","required":false,"default":"","description":"Specific zone (empty = full config + all zones).","validation":{"pattern":"^([a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252})?$"}}],"examples":[{"title":"Reload one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then rndc reload; else rndc reload \"${1}\"; fi","emisar","{{ args.zone }}"]}},{"id":"bind.rndc_stats","title":"rndc stats + read dump","summary":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","description":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","kind":"exec","risk":"medium","side_effects":["Writes /var/named/data/named_stats.txt.","Rewrites BIND's own stats file; no service impact."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","rndc stats || { echo 'rndc stats failed; not reading the previous dump' >&2; exit 1; }; sleep 1; cat /var/named/data/named_stats.txt 2>/dev/null || cat /var/cache/bind/named.stats"]}},{"id":"bind.rndc_status","title":"rndc status","summary":"Show named version, uptime, zone count, configured vs current settings.","description":"Show named version, uptime, zone count, configured vs current settings.","kind":"exec","risk":"low","side_effects":["One rndc call.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["status"]}},{"id":"bind.rndc_thaw","title":"rndc thaw <zone>","summary":"Unfreeze a zone — resumes dynamic updates + reloads it.","description":"Unfreeze a zone — resumes dynamic updates + reloads it.","kind":"exec","risk":"medium","side_effects":["Dynamic updates resume.","Zone reloads."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Thaw after edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["thaw","{{ args.zone }}"]}},{"id":"bind.zone_dump","title":"dig @localhost <zone> AXFR","summary":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","description":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","kind":"exec","risk":"low","side_effects":["One AXFR query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"AXFR one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.zone }}","AXFR"]}},{"id":"bind.zone_serial","title":"SOA serial of <zone>","summary":"Show SOA serial from localhost — use to confirm a zone reloaded.","description":"Show SOA serial from localhost — use to confirm a zone reloaded.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Serial","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","soa=$(dig @127.0.0.1 \"$1\" SOA +short) || exit 1; printf '%s\\n' \"$soa\" | awk '{print $3}'","emisar","{{ args.zone }}"]}}],"previous_versions":[{"version":"0.1.14","content_hash":"sha256:a378b636334931886a2fffbc4ff6f884b840ec61a22b9fc4a6da6d56354f63e4","tarball_url":"https://registry.emisar.dev/v1/packs/bind/0.1.14/a378b636334931886a2fffbc4ff6f884b840ec61a22b9fc4a6da6d56354f63e4/pack.tar.gz","actions":[{"id":"bind.named_checkconf","title":"named-checkconf","summary":"Validate named.conf syntax. Run before any rndc reload.","description":"Validate named.conf syntax. Run before any rndc reload.","kind":"exec","risk":"low","side_effects":["Reads named.conf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"named-checkconf","argv":[]}},{"id":"bind.named_checkzone","title":"named-checkzone <zone> <file>","summary":"Validate one zone file.","description":"Validate one zone file.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"file","type":"string","required":true,"description":"Zone file path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/bind","/var/lib/bind","/var/named","/etc/named"]}}],"examples":[{"title":"Check zone file","args":{"file":"/etc/bind/db.example.com","zone":"example.com"}}],"search_terms":[],"command":{"binary":"named-checkzone","argv":["{{ args.zone }}","{{ args.file }}"]}},{"id":"bind.query_local","title":"dig @localhost <name> <type>","summary":"Resolve one name against the local named.","description":"Resolve one name against the local named.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Name to query.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SOA","PTR","SRV","CAA","ANY"]}}],"examples":[{"title":"Local lookup","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.name }}","{{ args.type }}","+short"]}},{"id":"bind.rndc_flush","title":"rndc flush","summary":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","description":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","kind":"exec","risk":"medium","side_effects":["Resolver cache is emptied.","Brief upstream-query spike as cache repopulates."],"args":[],"examples":[{"title":"Flush all caches","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["flush"]}},{"id":"bind.rndc_freeze","title":"rndc freeze <zone>","summary":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","description":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","kind":"exec","risk":"medium","side_effects":["Dynamic-update writes paused for the zone.","Reverse with rndc thaw."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Freeze before edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["freeze","{{ args.zone }}"]}},{"id":"bind.rndc_reload","title":"rndc reload [zone]","summary":"Reload named config (or one zone). Validates first if zone specified.","description":"Reload named config (or one zone). Validates first if zone specified.","kind":"exec","risk":"high","side_effects":["Brief lock on the zone(s) being reloaded.","Invalid config aborts the reload; old data stays in place."],"args":[{"name":"zone","type":"string","required":false,"default":"","description":"Specific zone (empty = full config + all zones).","validation":{"pattern":"^([a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252})?$"}}],"examples":[{"title":"Reload one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then rndc reload; else rndc reload \"${1}\"; fi","emisar","{{ args.zone }}"]}},{"id":"bind.rndc_stats","title":"rndc stats + read dump","summary":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","description":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","kind":"exec","risk":"medium","side_effects":["Writes /var/named/data/named_stats.txt.","Rewrites BIND's own stats file; no service impact."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","rndc stats; sleep 1; cat /var/named/data/named_stats.txt 2>/dev/null || cat /var/cache/bind/named.stats"]}},{"id":"bind.rndc_status","title":"rndc status","summary":"Show named version, uptime, zone count, configured vs current settings.","description":"Show named version, uptime, zone count, configured vs current settings.","kind":"exec","risk":"low","side_effects":["One rndc call.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["status"]}},{"id":"bind.rndc_thaw","title":"rndc thaw <zone>","summary":"Unfreeze a zone — resumes dynamic updates + reloads it.","description":"Unfreeze a zone — resumes dynamic updates + reloads it.","kind":"exec","risk":"medium","side_effects":["Dynamic updates resume.","Zone reloads."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Thaw after edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["thaw","{{ args.zone }}"]}},{"id":"bind.zone_dump","title":"dig @localhost <zone> AXFR","summary":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","description":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","kind":"exec","risk":"low","side_effects":["One AXFR query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"AXFR one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.zone }}","AXFR"]}},{"id":"bind.zone_serial","title":"SOA serial of <zone>","summary":"Show SOA serial from localhost — use to confirm a zone reloaded.","description":"Show SOA serial from localhost — use to confirm a zone reloaded.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Serial","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","soa=$(dig @127.0.0.1 \"$1\" SOA +short) || exit 1; printf '%s\\n' \"$soa\" | awk '{print $3}'","emisar","{{ args.zone }}"]}}]},{"version":"0.1.12","content_hash":"sha256:528f37bcb59292ea84cce2458bbb645bdb4fb50887eeea1a07e12bfba9b73ea5","tarball_url":"https://registry.emisar.dev/v1/packs/bind/0.1.12/528f37bcb59292ea84cce2458bbb645bdb4fb50887eeea1a07e12bfba9b73ea5/pack.tar.gz","actions":[{"id":"bind.named_checkconf","title":"named-checkconf","summary":"Validate named.conf syntax. Run before any rndc reload.","description":"Validate named.conf syntax. Run before any rndc reload.","kind":"exec","risk":"low","side_effects":["Reads named.conf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"named-checkconf","argv":[]}},{"id":"bind.named_checkzone","title":"named-checkzone <zone> <file>","summary":"Validate one zone file.","description":"Validate one zone file.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"file","type":"string","required":true,"description":"Zone file path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/bind","/var/lib/bind","/var/named","/etc/named"]}}],"examples":[{"title":"Check zone file","args":{"file":"/etc/bind/db.example.com","zone":"example.com"}}],"search_terms":[],"command":{"binary":"named-checkzone","argv":["{{ args.zone }}","{{ args.file }}"]}},{"id":"bind.query_local","title":"dig @localhost <name> <type>","summary":"Resolve one name against the local named.","description":"Resolve one name against the local named.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Name to query.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SOA","PTR","SRV","CAA","ANY"]}}],"examples":[{"title":"Local lookup","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.name }}","{{ args.type }}","+short"]}},{"id":"bind.rndc_flush","title":"rndc flush","summary":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","description":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","kind":"exec","risk":"medium","side_effects":["Resolver cache is emptied.","Brief upstream-query spike as cache repopulates."],"args":[],"examples":[{"title":"Flush all caches","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["flush"]}},{"id":"bind.rndc_freeze","title":"rndc freeze <zone>","summary":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","description":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","kind":"exec","risk":"medium","side_effects":["Dynamic-update writes paused for the zone.","Reverse with rndc thaw."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Freeze before edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["freeze","{{ args.zone }}"]}},{"id":"bind.rndc_reload","title":"rndc reload [zone]","summary":"Reload named config (or one zone). Validates first if zone specified.","description":"Reload named config (or one zone). Validates first if zone specified.","kind":"exec","risk":"high","side_effects":["Brief lock on the zone(s) being reloaded.","Invalid config aborts the reload; old data stays in place."],"args":[{"name":"zone","type":"string","required":false,"default":"","description":"Specific zone (empty = full config + all zones).","validation":{"pattern":"^([a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252})?$"}}],"examples":[{"title":"Reload one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then rndc reload; else rndc reload \"${1}\"; fi","emisar","{{ args.zone }}"]}},{"id":"bind.rndc_stats","title":"rndc stats + read dump","summary":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","description":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","kind":"exec","risk":"medium","side_effects":["Writes /var/named/data/named_stats.txt.","Rewrites BIND's own stats file; no service impact."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","rndc stats; sleep 1; cat /var/named/data/named_stats.txt 2>/dev/null || cat /var/cache/bind/named.stats"]}},{"id":"bind.rndc_status","title":"rndc status","summary":"Show named version, uptime, zone count, configured vs current settings.","description":"Show named version, uptime, zone count, configured vs current settings.","kind":"exec","risk":"low","side_effects":["One rndc call.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["status"]}},{"id":"bind.rndc_thaw","title":"rndc thaw <zone>","summary":"Unfreeze a zone — resumes dynamic updates + reloads it.","description":"Unfreeze a zone — resumes dynamic updates + reloads it.","kind":"exec","risk":"medium","side_effects":["Dynamic updates resume.","Zone reloads."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Thaw after edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["thaw","{{ args.zone }}"]}},{"id":"bind.zone_dump","title":"dig @localhost <zone> AXFR","summary":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","description":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","kind":"exec","risk":"low","side_effects":["One AXFR query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"AXFR one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.zone }}","AXFR"]}},{"id":"bind.zone_serial","title":"SOA serial of <zone>","summary":"Show SOA serial from localhost — use to confirm a zone reloaded.","description":"Show SOA serial from localhost — use to confirm a zone reloaded.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Serial","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","soa=$(dig @127.0.0.1 \"$1\" SOA +short) || exit 1; printf '%s\\n' \"$soa\" | awk '{print $3}'","emisar","{{ args.zone }}"]}}]},{"version":"0.1.11","content_hash":"sha256:a8d9c241c08706ac414fade6a6c4f1070c5d38b3d48d4a2d4803bdf16bc703d4","tarball_url":"https://registry.emisar.dev/v1/packs/bind/0.1.11/a8d9c241c08706ac414fade6a6c4f1070c5d38b3d48d4a2d4803bdf16bc703d4/pack.tar.gz","actions":[{"id":"bind.named_checkconf","title":"named-checkconf","summary":"Validate named.conf syntax. Run before any rndc reload.","description":"Validate named.conf syntax. Run before any rndc reload.","kind":"exec","risk":"low","side_effects":["Reads named.conf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"named-checkconf","argv":[]}},{"id":"bind.named_checkzone","title":"named-checkzone <zone> <file>","summary":"Validate one zone file.","description":"Validate one zone file.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"file","type":"string","required":true,"description":"Zone file path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/bind","/var/lib/bind","/var/named","/etc/named"]}}],"examples":[{"title":"Check zone file","args":{"file":"/etc/bind/db.example.com","zone":"example.com"}}],"search_terms":[],"command":{"binary":"named-checkzone","argv":["{{ args.zone }}","{{ args.file }}"]}},{"id":"bind.query_local","title":"dig @localhost <name> <type>","summary":"Resolve one name against the local named.","description":"Resolve one name against the local named.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Name to query.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SOA","PTR","SRV","CAA","ANY"]}}],"examples":[{"title":"Local lookup","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.name }}","{{ args.type }}","+short"]}},{"id":"bind.rndc_flush","title":"rndc flush","summary":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","description":"Flush the resolver cache. Use after a downstream domain's records change and BIND is still serving stale answers. All clients hit upstream until cache repopulates.","kind":"exec","risk":"medium","side_effects":["Resolver cache is emptied.","Brief upstream-query spike as cache repopulates."],"args":[],"examples":[{"title":"Flush all caches","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["flush"]}},{"id":"bind.rndc_freeze","title":"rndc freeze <zone>","summary":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","description":"Freeze a zone (suspend dynamic updates) — used before editing zone file by hand.","kind":"exec","risk":"medium","side_effects":["Dynamic-update writes paused for the zone.","Reverse with rndc thaw."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Freeze before edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["freeze","{{ args.zone }}"]}},{"id":"bind.rndc_reload","title":"rndc reload [zone]","summary":"Reload named config (or one zone). Validates first if zone specified.","description":"Reload named config (or one zone). Validates first if zone specified.","kind":"exec","risk":"high","side_effects":["Brief lock on the zone(s) being reloaded.","Invalid config aborts the reload; old data stays in place."],"args":[{"name":"zone","type":"string","required":false,"default":"","description":"Specific zone (empty = full config + all zones).","validation":{"pattern":"^([a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252})?$"}}],"examples":[{"title":"Reload one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then rndc reload; else rndc reload \"${1}\"; fi","emisar","{{ args.zone }}"]}},{"id":"bind.rndc_stats","title":"rndc stats + read dump","summary":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","description":"Force a stats dump and read it. Includes query counts, cache stats, NSID.","kind":"exec","risk":"low","side_effects":["Writes /var/named/data/named_stats.txt.","Read-only-ish — file rewrite, no service impact."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","rndc stats; sleep 1; cat /var/named/data/named_stats.txt 2>/dev/null || cat /var/cache/bind/named.stats"]}},{"id":"bind.rndc_status","title":"rndc status","summary":"Show named version, uptime, zone count, configured vs current settings.","description":"Show named version, uptime, zone count, configured vs current settings.","kind":"exec","risk":"low","side_effects":["One rndc call.","Read-only."],"args":[],"examples":[{"title":"Status","args":{}}],"search_terms":[],"command":{"binary":"rndc","argv":["status"]}},{"id":"bind.rndc_thaw","title":"rndc thaw <zone>","summary":"Unfreeze a zone — resumes dynamic updates + reloads it.","description":"Unfreeze a zone — resumes dynamic updates + reloads it.","kind":"exec","risk":"medium","side_effects":["Dynamic updates resume.","Zone reloads."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Thaw after edit","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"rndc","argv":["thaw","{{ args.zone }}"]}},{"id":"bind.zone_dump","title":"dig @localhost <zone> AXFR","summary":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","description":"Dump zone transfer from localhost (requires allow-transfer to include 127.0.0.1).","kind":"exec","risk":"low","side_effects":["One AXFR query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"AXFR one zone","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["@127.0.0.1","{{ args.zone }}","AXFR"]}},{"id":"bind.zone_serial","title":"SOA serial of <zone>","summary":"Show SOA serial from localhost — use to confirm a zone reloaded.","description":"Show SOA serial from localhost — use to confirm a zone reloaded.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"zone","type":"string","required":true,"description":"Zone name.","validation":{"pattern":"^[a-zA-Z0-9.][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"Serial","args":{"zone":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","soa=$(dig @127.0.0.1 \"$1\" SOA +short) || exit 1; printf '%s\\n' \"$soa\" | awk '{print $3}'","emisar","{{ args.zone }}"]}}]}],"retired_below":"0.1.7"},{"id":"bonding","name":"Linux network bonding","version":"0.1.4","description":"Inspect Linux network bonding / LACP: list bond interfaces, read a bond's full status from /proc/net/bonding (mode, LACP actor/partner state, per-slave link status), and show link-layer details. Read-only.","vendor":"emisar","homepage":"https://emisar.dev/packs/bonding","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/bonding","content_hash":"sha256:97bb227b426b5a285fbe0b5d935d83f834f3e632e3f7d2e2bb8596b707476d40","tarball_url":"https://registry.emisar.dev/v1/packs/bonding/0.1.4/97bb227b426b5a285fbe0b5d935d83f834f3e632e3f7d2e2bb8596b707476d40/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Reads the host's bonding state from `/proc/net/bonding` and `ip`. No credentials needed; the reads work as any user.","notes":["Pass the bond interface name (e.g. bond0) to bonding.status / bonding.link. /proc/net/bonding/<bond> exists only when the bonding module is loaded and that bond is configured."],"verify":"bonding.list"},"actions":[{"id":"bonding.link","title":"ip -d link show <bond>","summary":"Show link-layer + bond detail for one interface (state, MTU, mode, xmit hash, LACP rate).","description":"Show link-layer + bond detail for one interface (state, MTU, mode, xmit hash, LACP rate).","kind":"exec","risk":"low","side_effects":["One link query.","Read-only."],"args":[{"name":"bond","type":"string","required":true,"description":"Bond interface name (e.g. bond0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"bond0 link detail","args":{"bond":"bond0"}}],"search_terms":[],"command":{"binary":"ip","argv":["-d","link","show","{{ args.bond }}"]}},{"id":"bonding.list","title":"ip -d link show type bond","summary":"List bond interfaces with their link-layer and bond-mode details.","description":"List bond interfaces with their link-layer and bond-mode details.","kind":"exec","risk":"low","side_effects":["One link query.","Read-only."],"args":[],"examples":[{"title":"List bonds","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["-d","link","show","type","bond"]}},{"id":"bonding.status","title":"cat /proc/net/bonding/<bond>","summary":"Show full bond status from /proc/net/bonding/<bond> — bonding mode, MII status, and for 802.3ad (LACP) the actor/partner state plus each slave's link state and aggregator id.","description":"Show full bond status from /proc/net/bonding/<bond> — bonding mode, MII status, and for 802.3ad (LACP) the actor/partner state plus each slave's link state and aggregator id.","kind":"exec","risk":"low","side_effects":["One file read under /proc.","Read-only."],"args":[{"name":"bond","type":"string","required":true,"description":"Bond interface name (e.g. bond0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"bond0 LACP + slave status","args":{"bond":"bond0"}}],"search_terms":["degraded","failover"],"command":{"binary":"cat","argv":["/proc/net/bonding/{{ args.bond }}"]}}],"previous_versions":[{"version":"0.1.2","content_hash":"sha256:a47698f47c11140a959cfa7e5c08f46a932eb6548feebe99ff70de79f59adf8b","tarball_url":"https://registry.emisar.dev/v1/packs/bonding/0.1.2/a47698f47c11140a959cfa7e5c08f46a932eb6548feebe99ff70de79f59adf8b/pack.tar.gz","actions":[{"id":"bonding.link","title":"ip -d link show <bond>","summary":"Show link-layer + bond detail for one interface (state, MTU, mode, xmit hash, LACP rate).","description":"Show link-layer + bond detail for one interface (state, MTU, mode, xmit hash, LACP rate).","kind":"exec","risk":"low","side_effects":["One link query.","Read-only."],"args":[{"name":"bond","type":"string","required":true,"description":"Bond interface name (e.g. bond0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"bond0 link detail","args":{"bond":"bond0"}}],"search_terms":[],"command":{"binary":"ip","argv":["-d","link","show","{{ args.bond }}"]}},{"id":"bonding.list","title":"ip -d link show type bond","summary":"List bond interfaces with their link-layer and bond-mode details.","description":"List bond interfaces with their link-layer and bond-mode details.","kind":"exec","risk":"low","side_effects":["One link query.","Read-only."],"args":[],"examples":[{"title":"List bonds","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["-d","link","show","type","bond"]}},{"id":"bonding.status","title":"cat /proc/net/bonding/<bond>","summary":"Show full bond status from /proc/net/bonding/<bond> — bonding mode, MII status, and for 802.3ad (LACP) the actor/partner state plus each slave's link state and aggregator id.","description":"Show full bond status from /proc/net/bonding/<bond> — bonding mode, MII status, and for 802.3ad (LACP) the actor/partner state plus each slave's link state and aggregator id.","kind":"exec","risk":"low","side_effects":["One file read under /proc.","Read-only."],"args":[{"name":"bond","type":"string","required":true,"description":"Bond interface name (e.g. bond0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"bond0 LACP + slave status","args":{"bond":"bond0"}}],"search_terms":["degraded","failover"],"command":{"binary":"cat","argv":["/proc/net/bonding/{{ args.bond }}"]}}]},{"version":"0.1.1","content_hash":"sha256:4a14e761267488e26cb5d47d1c73671283fe6ea3d57207c4504d767c195d4eaa","tarball_url":"https://registry.emisar.dev/v1/packs/bonding/0.1.1/4a14e761267488e26cb5d47d1c73671283fe6ea3d57207c4504d767c195d4eaa/pack.tar.gz","actions":[{"id":"bonding.link","title":"ip -d link show <bond>","summary":"Show link-layer + bond detail for one interface (state, MTU, mode, xmit hash, LACP rate).","description":"Show link-layer + bond detail for one interface (state, MTU, mode, xmit hash, LACP rate).","kind":"exec","risk":"low","side_effects":["One link query.","Read-only."],"args":[{"name":"bond","type":"string","required":true,"description":"Bond interface name (e.g. bond0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"bond0 link detail","args":{"bond":"bond0"}}],"search_terms":[],"command":{"binary":"ip","argv":["-d","link","show","{{ args.bond }}"]}},{"id":"bonding.list","title":"ip -d link show type bond","summary":"List bond interfaces with their link-layer and bond-mode details.","description":"List bond interfaces with their link-layer and bond-mode details.","kind":"exec","risk":"low","side_effects":["One link query.","Read-only."],"args":[],"examples":[{"title":"List bonds","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["-d","link","show","type","bond"]}},{"id":"bonding.status","title":"cat /proc/net/bonding/<bond>","summary":"Show full bond status from /proc/net/bonding/<bond> — bonding mode, MII status, and for 802.3ad (LACP) the actor/partner state plus each slave's link state and aggregator id.","description":"Show full bond status from /proc/net/bonding/<bond> — bonding mode, MII status, and for 802.3ad (LACP) the actor/partner state plus each slave's link state and aggregator id.","kind":"exec","risk":"low","side_effects":["One file read under /proc.","Read-only."],"args":[{"name":"bond","type":"string","required":true,"description":"Bond interface name (e.g. bond0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"bond0 LACP + slave status","args":{"bond":"bond0"}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/net/bonding/{{ args.bond }}"]}}]}]},{"id":"bunnycdn","name":"bunny.net CDN operations","version":"0.1.8","description":"Governed bunny.net Pull Zone lifecycle, cache, hostname, access-control, statistics, request-log, origin-error, and billing-usage operations. Auth via BUNNY_API_KEY on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/bunnycdn","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/bunnycdn","content_hash":"sha256:bf0627930b2c5fcfd7d6bd7b059b3c5382b7a2d7c6d112eb14ae175ab3e2c682","tarball_url":"https://registry.emisar.dev/v1/packs/bunnycdn/0.1.8/bf0627930b2c5fcfd7d6bd7b059b3c5382b7a2d7c6d112eb14ae175ab3e2c682/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Calls the bunny.net Core, CDN Logging v2, and Origin Errors APIs over HTTPS. `BUNNY_API_KEY` is sent in the AccessKey header over curl stdin and is never placed in argv or action output. Allowlist the variable in the runner's `execution.inherit_env` configuration.","env":[{"name":"BUNNY_API_KEY","required":true,"description":"bunny.net account API key. Use a scratch or least-privilege account and gate mutation actions with policy."}],"notes":["The account API key is at [dash.bunny.net/account/settings](https://dash.bunny.net/account/settings) → API.","Request logs are retained by bunny.net for three days; bunny.logs returns one bounded page and bunny.log_usage_summary aggregates one bounded page.","Pull Zone credentials, certificate material, log-forwarding tokens, request authorization headers, and URL query strings are removed before output leaves the runner.","The pack covers Bunny CDN Pull Zones. Bunny Storage, DNS, Stream, Shield/WAF, custom-certificate private keys, token-key reset, and arbitrary edge-rule documents are separate trust surfaces."],"verify":"bunny.list_pull_zones"},"actions":[{"id":"bunny.add_allowed_referrer","title":"Add allowed referrer","summary":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","description":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy for the Pull Zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern accepted by Bunny.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Allow one site","args":{"hostname":"www.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_ip","title":"Add blocked IP address","summary":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","description":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and block.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Block one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_referrer","title":"Add blocked referrer","summary":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","description":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to block.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Block one site","args":{"hostname":"scraper.example","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_hostname","title":"Add Pull Zone hostname","summary":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","description":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","kind":"script","risk":"high","side_effects":["Attaches a custom hostname to the Pull Zone.","Can begin serving traffic after DNS points at Bunny."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to attach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Attach a hostname","args":{"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.billing_usage","title":"Get CDN billing usage","summary":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","description":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","kind":"script","risk":"low","side_effects":["Two read-only Core API requests."],"args":[],"examples":[{"title":"Account and Pull Zone usage","args":{}}],"search_terms":[]},{"id":"bunny.create_pull_zone","title":"Create Pull Zone","summary":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","description":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","kind":"script","risk":"high","side_effects":["Creates a persistent, billable Pull Zone.","Makes a new Bunny system hostname available for CDN traffic.","Enables anonymized logging when requested."],"args":[{"name":"name","type":"string","required":true,"description":"Account-unique Pull Zone name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$","max_length":64}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"tier","type":"string","required":false,"default":"premium","description":"Bunny Pull Zone traffic tier.","validation":{"enum":["premium","volume"]}},{"name":"enable_logging","type":"boolean","required":false,"default":true,"description":"Enable anonymized CDN request logging."},{"name":"enable_cache_slice","type":"boolean","required":false,"default":false,"description":"Enable cache slicing for large files and video."}],"examples":[{"title":"Create a logged video Pull Zone","args":{"enable_cache_slice":true,"name":"example-videos","origin_url":"https://origin.example.com/videos"}}],"search_terms":[]},{"id":"bunny.delete_pull_zone","title":"Delete Pull Zone","summary":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","description":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","kind":"script","risk":"critical","side_effects":["Permanently deletes the Pull Zone and its configuration.","Stops CDN delivery for every hostname attached to the zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID to delete.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Permanently delete a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.get_pull_zone","title":"Get Pull Zone","summary":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","description":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Inspect a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.list_pull_zones","title":"List Pull Zones","summary":"List one bounded page of Pull Zones accessible to the account API key.","description":"List one bounded page of Pull Zones accessible to the account API key.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"search","type":"string","required":false,"default":"","description":"Optional name search.","validation":{"pattern":"^[ -~]*$","max_length":128}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Pull Zones returned in this page.","validation":{"min":5,"max":1000}}],"examples":[{"title":"First page","args":{}}],"search_terms":[]},{"id":"bunny.list_regions","title":"List Bunny regions","summary":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","description":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[],"examples":[{"title":"Regions","args":{}}],"search_terms":[]},{"id":"bunny.log_usage_summary","title":"Summarize CDN log usage","summary":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","description":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","kind":"script","risk":"low","side_effects":["One read-only CDN Logging API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":1000,"description":"Maximum log entries aggregated in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order before aggregation.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Attribute bytes by path and cache state","args":{"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.logs","title":"Fetch CDN request logs","summary":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","description":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","kind":"script","risk":"medium","side_effects":["One CDN Logging API request.","Returns request-level client metadata into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes, such as 404,5xx.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses, such as HIT,MISS,STALE.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum log entries in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Recent cache misses for video paths","args":{"cache_status":"MISS","limit":100,"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.optimizer_statistics","title":"Get Optimizer statistics","summary":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","description":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Optimizer metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_errors","title":"Get origin error logs","summary":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","description":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","kind":"script","risk":"medium","side_effects":["One read-only Origin Errors API request.","Returns origin failure detail into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date","type":"string","required":true,"description":"UTC date in MM-DD-YYYY format.","validation":{"pattern":"^[0-9]{2}-[0-9]{2}-20[0-9]{2}$","max_length":10}}],"examples":[{"title":"Origin failures for one UTC day","args":{"date":"07-31-2026","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_shield_statistics","title":"Get Origin Shield queue statistics","summary":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","description":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Origin Shield queue","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_all_cache","title":"Purge entire Pull Zone cache","summary":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","description":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","kind":"script","risk":"critical","side_effects":["Removes all cached objects for the Pull Zone.","Sends subsequent requests to the origin until the cache re-warms.","Can cause an immediate origin-load and egress spike."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID whose complete cache will be purged.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Purge everything only after targeted purges are insufficient","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_tag","title":"Purge cache tag","summary":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","description":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","kind":"script","risk":"high","side_effects":["Removes every cached object carrying the tag in this Pull Zone.","Causes subsequent requests for matched objects to reach the origin."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"cache_tag","type":"string","required":true,"description":"Exact Bunny cache tag to purge.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,128}$","max_length":128}}],"examples":[{"title":"Purge one release tag","args":{"cache_tag":"release-2026-07-31","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_url","title":"Purge cached URL","summary":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","description":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute HTTPS CDN URL to purge. Query strings are sent to Bunny but removed from action output.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}},{"name":"async","type":"boolean","required":false,"default":false,"description":"Return after Bunny accepts the purge instead of waiting for completion."},{"name":"exact_path","type":"boolean","required":false,"default":false,"description":"When a URL ends in slash, purge only that exact path instead of a wildcard suffix."}],"examples":[{"title":"Purge one video","args":{"url":"https://cdn.example.com/video/intro.mp4"}}],"search_terms":[]},{"id":"bunny.remove_allowed_referrer","title":"Remove allowed referrer","summary":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","description":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and can block legitimate embeds."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to remove.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Remove one allowed site","args":{"hostname":"old.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_ip","title":"Remove blocked IP address","summary":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","description":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and unblock.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Unblock one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_referrer","title":"Remove blocked referrer","summary":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","description":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to unblock.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Unblock one site","args":{"hostname":"partner.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_hostname","title":"Remove Pull Zone hostname","summary":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","description":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","kind":"script","risk":"high","side_effects":["Detaches the custom hostname from the Pull Zone.","Interrupts CDN delivery through that hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to detach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Detach a hostname","args":{"hostname":"old-cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.safehop_statistics","title":"Get SafeHop statistics","summary":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","description":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"SafeHop metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_cache_behavior","title":"Change one Pull Zone cache behavior","summary":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","description":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","kind":"script","risk":"high","side_effects":["Changes one Pull Zone caching behavior immediately.","Can increase misses, serve stale objects, or alter query-string cache keys depending on the selected setting."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"setting","type":"string","required":true,"description":"Declared cache behavior to change.","validation":{"enum":["ignore_query_strings","cache_slice","smart_cache","cache_error_responses","background_update","stale_while_offline","stale_while_updating","request_coalescing","query_string_ordering"]}},{"name":"enabled","type":"boolean","required":true,"description":"New setting value."}],"examples":[{"title":"Serve stale cache while the origin is offline","args":{"enabled":true,"pull_zone_id":123456,"setting":"stale_while_offline"}}],"search_terms":[]},{"id":"bunny.set_cache_ttl","title":"Change Pull Zone cache TTLs","summary":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","description":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","kind":"script","risk":"high","side_effects":["Changes caching for subsequent responses on the Pull Zone.","Does not purge objects already stored at the edge or in browsers."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"edge_seconds","type":"string","required":false,"default":"unchanged","description":"Edge cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}},{"name":"browser_seconds","type":"string","required":false,"default":"unchanged","description":"Browser cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}}],"examples":[{"title":"Cache at edge for one day and in browsers for one hour","args":{"browser_seconds":"3600","edge_seconds":"86400","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_force_ssl","title":"Change hostname Force SSL","summary":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","description":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","kind":"script","risk":"high","side_effects":["Changes redirect and transport enforcement for one hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Attached Pull Zone hostname.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}},{"name":"enabled","type":"boolean","required":true,"description":"New Force SSL state."}],"examples":[{"title":"Force HTTPS","args":{"enabled":true,"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_logging","title":"Change Pull Zone logging","summary":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","description":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","kind":"script","risk":"medium","side_effects":["Changes whether Bunny records CDN requests for this Pull Zone.","Enforces IP anonymization and selects plain or JSON storage format."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New request-logging state."},{"name":"anonymization","type":"string","required":false,"default":"last_octet","description":"IP anonymization strength.","validation":{"enum":["last_octet","drop_all"]}},{"name":"format","type":"string","required":false,"default":"json","description":"Log storage format.","validation":{"enum":["plain","json"]}}],"examples":[{"title":"Enable anonymized JSON logs","args":{"enabled":true,"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin","title":"Change Pull Zone origin","summary":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","description":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","kind":"script","risk":"high","side_effects":["Subsequent cache misses and revalidations use the new origin.","Can change the Host header sent to the origin.","Can disable origin certificate verification when explicitly requested."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"origin_host_header","type":"string","required":false,"default":"","description":"Optional Host header sent to the origin; empty leaves it unchanged.","validation":{"pattern":"^(|[A-Za-z0-9][A-Za-z0-9.-]{0,252})$","max_length":253}},{"name":"verify_origin_ssl","type":"boolean","required":false,"default":true,"description":"Verify the origin TLS certificate. Keep enabled unless a separately approved exception requires otherwise."}],"examples":[{"title":"Move to a verified origin","args":{"origin_host_header":"new-origin.example.com","origin_url":"https://new-origin.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin_shield","title":"Change Pull Zone Origin Shield","summary":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","description":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","kind":"script","risk":"high","side_effects":["Changes whether cache misses pass through Origin Shield.","A supplied zone code changes the shield location.","Origin Shield pricing and latency may change."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New Origin Shield state."},{"name":"zone_code","type":"string","required":false,"default":"","description":"Optional Bunny region code from bunny.list_regions; empty leaves the location unchanged.","validation":{"pattern":"^(|[A-Za-z0-9-]{1,32})$","max_length":32}}],"examples":[{"title":"Enable Origin Shield in one region","args":{"enabled":true,"pull_zone_id":123456,"zone_code":"DE"}}],"search_terms":[]},{"id":"bunny.statistics","title":"Get CDN statistics","summary":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","description":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; empty uses Bunny's default window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"pull_zone_id","type":"integer","required":false,"default":0,"description":"Pull Zone ID, or 0 for account-wide statistics.","validation":{"min":0,"max":9007199254740991}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets and preserve exact hours."}],"examples":[{"title":"One Pull Zone over Bunny's default window","args":{"pull_zone_id":123456}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.7","content_hash":"sha256:2cdb7d64c5af70f9007d37a999f9f38b595d0f27edfb18af237f3b9bb43dfb11","tarball_url":"https://registry.emisar.dev/v1/packs/bunnycdn/0.1.7/2cdb7d64c5af70f9007d37a999f9f38b595d0f27edfb18af237f3b9bb43dfb11/pack.tar.gz","actions":[{"id":"bunny.add_allowed_referrer","title":"Add allowed referrer","summary":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","description":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy for the Pull Zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern accepted by Bunny.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Allow one site","args":{"hostname":"www.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_ip","title":"Add blocked IP address","summary":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","description":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and block.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Block one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_referrer","title":"Add blocked referrer","summary":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","description":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to block.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Block one site","args":{"hostname":"scraper.example","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_hostname","title":"Add Pull Zone hostname","summary":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","description":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","kind":"script","risk":"high","side_effects":["Attaches a custom hostname to the Pull Zone.","Can begin serving traffic after DNS points at Bunny."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to attach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Attach a hostname","args":{"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.billing_usage","title":"Get CDN billing usage","summary":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","description":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","kind":"script","risk":"low","side_effects":["Two read-only Core API requests."],"args":[],"examples":[{"title":"Account and Pull Zone usage","args":{}}],"search_terms":[]},{"id":"bunny.create_pull_zone","title":"Create Pull Zone","summary":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","description":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","kind":"script","risk":"high","side_effects":["Creates a persistent, billable Pull Zone.","Makes a new Bunny system hostname available for CDN traffic.","Enables anonymized logging when requested."],"args":[{"name":"name","type":"string","required":true,"description":"Account-unique Pull Zone name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$","max_length":64}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"tier","type":"string","required":false,"default":"premium","description":"Bunny Pull Zone traffic tier.","validation":{"enum":["premium","volume"]}},{"name":"enable_logging","type":"boolean","required":false,"default":true,"description":"Enable anonymized CDN request logging."},{"name":"enable_cache_slice","type":"boolean","required":false,"default":false,"description":"Enable cache slicing for large files and video."}],"examples":[{"title":"Create a logged video Pull Zone","args":{"enable_cache_slice":true,"name":"example-videos","origin_url":"https://origin.example.com/videos"}}],"search_terms":[]},{"id":"bunny.delete_pull_zone","title":"Delete Pull Zone","summary":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","description":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","kind":"script","risk":"critical","side_effects":["Permanently deletes the Pull Zone and its configuration.","Stops CDN delivery for every hostname attached to the zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID to delete.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Permanently delete a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.get_pull_zone","title":"Get Pull Zone","summary":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","description":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Inspect a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.list_pull_zones","title":"List Pull Zones","summary":"List one bounded page of Pull Zones accessible to the account API key.","description":"List one bounded page of Pull Zones accessible to the account API key.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"search","type":"string","required":false,"default":"","description":"Optional name search.","validation":{"pattern":"^[ -~]*$","max_length":128}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Pull Zones returned in this page.","validation":{"min":5,"max":1000}}],"examples":[{"title":"First page","args":{}}],"search_terms":[]},{"id":"bunny.list_regions","title":"List Bunny regions","summary":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","description":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[],"examples":[{"title":"Regions","args":{}}],"search_terms":[]},{"id":"bunny.log_usage_summary","title":"Summarize CDN log usage","summary":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","description":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","kind":"script","risk":"low","side_effects":["One read-only CDN Logging API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":1000,"description":"Maximum log entries aggregated in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order before aggregation.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Attribute bytes by path and cache state","args":{"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.logs","title":"Fetch CDN request logs","summary":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","description":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","kind":"script","risk":"medium","side_effects":["One CDN Logging API request.","Returns request-level client metadata into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes, such as 404,5xx.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses, such as HIT,MISS,STALE.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum log entries in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Recent cache misses for video paths","args":{"cache_status":"MISS","limit":100,"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.optimizer_statistics","title":"Get Optimizer statistics","summary":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","description":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Optimizer metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_errors","title":"Get origin error logs","summary":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","description":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","kind":"script","risk":"medium","side_effects":["One read-only Origin Errors API request.","Returns origin failure detail into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date","type":"string","required":true,"description":"UTC date in MM-DD-YYYY format.","validation":{"pattern":"^[0-9]{2}-[0-9]{2}-20[0-9]{2}$","max_length":10}}],"examples":[{"title":"Origin failures for one UTC day","args":{"date":"07-31-2026","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_shield_statistics","title":"Get Origin Shield queue statistics","summary":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","description":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Origin Shield queue","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_all_cache","title":"Purge entire Pull Zone cache","summary":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","description":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","kind":"script","risk":"critical","side_effects":["Removes all cached objects for the Pull Zone.","Sends subsequent requests to the origin until the cache re-warms.","Can cause an immediate origin-load and egress spike."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID whose complete cache will be purged.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Purge everything only after targeted purges are insufficient","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_tag","title":"Purge cache tag","summary":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","description":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","kind":"script","risk":"high","side_effects":["Removes every cached object carrying the tag in this Pull Zone.","Causes subsequent requests for matched objects to reach the origin."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"cache_tag","type":"string","required":true,"description":"Exact Bunny cache tag to purge.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,128}$","max_length":128}}],"examples":[{"title":"Purge one release tag","args":{"cache_tag":"release-2026-07-31","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_url","title":"Purge cached URL","summary":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","description":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute HTTPS CDN URL to purge. Query strings are sent to Bunny but removed from action output.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}},{"name":"async","type":"boolean","required":false,"default":false,"description":"Return after Bunny accepts the purge instead of waiting for completion."},{"name":"exact_path","type":"boolean","required":false,"default":false,"description":"When a URL ends in slash, purge only that exact path instead of a wildcard suffix."}],"examples":[{"title":"Purge one video","args":{"url":"https://cdn.example.com/video/intro.mp4"}}],"search_terms":[]},{"id":"bunny.remove_allowed_referrer","title":"Remove allowed referrer","summary":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","description":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and can block legitimate embeds."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to remove.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Remove one allowed site","args":{"hostname":"old.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_ip","title":"Remove blocked IP address","summary":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","description":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and unblock.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Unblock one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_referrer","title":"Remove blocked referrer","summary":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","description":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to unblock.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Unblock one site","args":{"hostname":"partner.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_hostname","title":"Remove Pull Zone hostname","summary":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","description":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","kind":"script","risk":"high","side_effects":["Detaches the custom hostname from the Pull Zone.","Interrupts CDN delivery through that hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to detach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Detach a hostname","args":{"hostname":"old-cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.safehop_statistics","title":"Get SafeHop statistics","summary":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","description":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"SafeHop metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_cache_behavior","title":"Change one Pull Zone cache behavior","summary":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","description":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","kind":"script","risk":"high","side_effects":["Changes one Pull Zone caching behavior immediately.","Can increase misses, serve stale objects, or alter query-string cache keys depending on the selected setting."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"setting","type":"string","required":true,"description":"Declared cache behavior to change.","validation":{"enum":["ignore_query_strings","cache_slice","smart_cache","cache_error_responses","background_update","stale_while_offline","stale_while_updating","request_coalescing","query_string_ordering"]}},{"name":"enabled","type":"boolean","required":true,"description":"New setting value."}],"examples":[{"title":"Serve stale cache while the origin is offline","args":{"enabled":true,"pull_zone_id":123456,"setting":"stale_while_offline"}}],"search_terms":[]},{"id":"bunny.set_cache_ttl","title":"Change Pull Zone cache TTLs","summary":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","description":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","kind":"script","risk":"high","side_effects":["Changes caching for subsequent responses on the Pull Zone.","Does not purge objects already stored at the edge or in browsers."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"edge_seconds","type":"string","required":false,"default":"unchanged","description":"Edge cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}},{"name":"browser_seconds","type":"string","required":false,"default":"unchanged","description":"Browser cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}}],"examples":[{"title":"Cache at edge for one day and in browsers for one hour","args":{"browser_seconds":"3600","edge_seconds":"86400","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_force_ssl","title":"Change hostname Force SSL","summary":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","description":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","kind":"script","risk":"high","side_effects":["Changes redirect and transport enforcement for one hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Attached Pull Zone hostname.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}},{"name":"enabled","type":"boolean","required":true,"description":"New Force SSL state."}],"examples":[{"title":"Force HTTPS","args":{"enabled":true,"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_logging","title":"Change Pull Zone logging","summary":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","description":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","kind":"script","risk":"medium","side_effects":["Changes whether Bunny records CDN requests for this Pull Zone.","Enforces IP anonymization and selects plain or JSON storage format."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New request-logging state."},{"name":"anonymization","type":"string","required":false,"default":"last_octet","description":"IP anonymization strength.","validation":{"enum":["last_octet","drop_all"]}},{"name":"format","type":"string","required":false,"default":"json","description":"Log storage format.","validation":{"enum":["plain","json"]}}],"examples":[{"title":"Enable anonymized JSON logs","args":{"enabled":true,"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin","title":"Change Pull Zone origin","summary":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","description":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","kind":"script","risk":"high","side_effects":["Subsequent cache misses and revalidations use the new origin.","Can change the Host header sent to the origin.","Can disable origin certificate verification when explicitly requested."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"origin_host_header","type":"string","required":false,"default":"","description":"Optional Host header sent to the origin; empty leaves it unchanged.","validation":{"pattern":"^(|[A-Za-z0-9][A-Za-z0-9.-]{0,252})$","max_length":253}},{"name":"verify_origin_ssl","type":"boolean","required":false,"default":true,"description":"Verify the origin TLS certificate. Keep enabled unless a separately approved exception requires otherwise."}],"examples":[{"title":"Move to a verified origin","args":{"origin_host_header":"new-origin.example.com","origin_url":"https://new-origin.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin_shield","title":"Change Pull Zone Origin Shield","summary":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","description":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","kind":"script","risk":"high","side_effects":["Changes whether cache misses pass through Origin Shield.","A supplied zone code changes the shield location.","Origin Shield pricing and latency may change."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New Origin Shield state."},{"name":"zone_code","type":"string","required":false,"default":"","description":"Optional Bunny region code from bunny.list_regions; empty leaves the location unchanged.","validation":{"pattern":"^(|[A-Za-z0-9-]{1,32})$","max_length":32}}],"examples":[{"title":"Enable Origin Shield in one region","args":{"enabled":true,"pull_zone_id":123456,"zone_code":"DE"}}],"search_terms":[]},{"id":"bunny.statistics","title":"Get CDN statistics","summary":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","description":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; empty uses Bunny's default window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"pull_zone_id","type":"integer","required":false,"default":0,"description":"Pull Zone ID, or 0 for account-wide statistics.","validation":{"min":0,"max":9007199254740991}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets and preserve exact hours."}],"examples":[{"title":"One Pull Zone over Bunny's default window","args":{"pull_zone_id":123456}}],"search_terms":[]}]},{"version":"0.1.3","content_hash":"sha256:eae9583b6f6f033ecb1908b1c7b18f1d712f576e326cd588a37acc1606f0cb22","tarball_url":"https://registry.emisar.dev/v1/packs/bunnycdn/0.1.3/eae9583b6f6f033ecb1908b1c7b18f1d712f576e326cd588a37acc1606f0cb22/pack.tar.gz","actions":[{"id":"bunny.add_allowed_referrer","title":"Add allowed referrer","summary":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","description":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy for the Pull Zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern accepted by Bunny.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Allow one site","args":{"hostname":"www.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_ip","title":"Add blocked IP address","summary":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","description":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and block.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Block one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_referrer","title":"Add blocked referrer","summary":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","description":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to block.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Block one site","args":{"hostname":"scraper.example","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_hostname","title":"Add Pull Zone hostname","summary":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","description":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","kind":"script","risk":"high","side_effects":["Attaches a custom hostname to the Pull Zone.","Can begin serving traffic after DNS points at Bunny."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to attach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Attach a hostname","args":{"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.billing_usage","title":"Get CDN billing usage","summary":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","description":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","kind":"script","risk":"low","side_effects":["Two read-only Core API requests."],"args":[],"examples":[{"title":"Account and Pull Zone usage","args":{}}],"search_terms":[]},{"id":"bunny.create_pull_zone","title":"Create Pull Zone","summary":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","description":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","kind":"script","risk":"high","side_effects":["Creates a persistent, billable Pull Zone.","Makes a new Bunny system hostname available for CDN traffic.","Enables anonymized logging when requested."],"args":[{"name":"name","type":"string","required":true,"description":"Account-unique Pull Zone name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$","max_length":64}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"tier","type":"string","required":false,"default":"premium","description":"Bunny Pull Zone traffic tier.","validation":{"enum":["premium","volume"]}},{"name":"enable_logging","type":"boolean","required":false,"default":true,"description":"Enable anonymized CDN request logging."},{"name":"enable_cache_slice","type":"boolean","required":false,"default":false,"description":"Enable cache slicing for large files and video."}],"examples":[{"title":"Create a logged video Pull Zone","args":{"enable_cache_slice":true,"name":"example-videos","origin_url":"https://origin.example.com/videos"}}],"search_terms":[]},{"id":"bunny.delete_pull_zone","title":"Delete Pull Zone","summary":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","description":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","kind":"script","risk":"critical","side_effects":["Permanently deletes the Pull Zone and its configuration.","Stops CDN delivery for every hostname attached to the zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID to delete.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Permanently delete a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.get_pull_zone","title":"Get Pull Zone","summary":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","description":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Inspect a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.list_pull_zones","title":"List Pull Zones","summary":"List one bounded page of Pull Zones accessible to the account API key.","description":"List one bounded page of Pull Zones accessible to the account API key.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"search","type":"string","required":false,"default":"","description":"Optional name search.","validation":{"pattern":"^[ -~]*$","max_length":128}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Pull Zones returned in this page.","validation":{"min":5,"max":1000}}],"examples":[{"title":"First page","args":{}}],"search_terms":[]},{"id":"bunny.list_regions","title":"List Bunny regions","summary":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","description":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[],"examples":[{"title":"Regions","args":{}}],"search_terms":[]},{"id":"bunny.log_usage_summary","title":"Summarize CDN log usage","summary":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","description":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","kind":"script","risk":"low","side_effects":["One read-only CDN Logging API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":1000,"description":"Maximum log entries aggregated in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order before aggregation.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Attribute bytes by path and cache state","args":{"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.logs","title":"Fetch CDN request logs","summary":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","description":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","kind":"script","risk":"medium","side_effects":["One CDN Logging API request.","Returns request-level client metadata into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes, such as 404,5xx.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses, such as HIT,MISS,STALE.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum log entries in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Recent cache misses for video paths","args":{"cache_status":"MISS","limit":100,"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.optimizer_statistics","title":"Get Optimizer statistics","summary":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","description":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Optimizer metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_errors","title":"Get origin error logs","summary":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","description":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","kind":"script","risk":"medium","side_effects":["One read-only Origin Errors API request.","Returns origin failure detail into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date","type":"string","required":true,"description":"UTC date in MM-DD-YYYY format.","validation":{"pattern":"^[0-9]{2}-[0-9]{2}-20[0-9]{2}$","max_length":10}}],"examples":[{"title":"Origin failures for one UTC day","args":{"date":"07-31-2026","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_shield_statistics","title":"Get Origin Shield queue statistics","summary":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","description":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Origin Shield queue","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_all_cache","title":"Purge entire Pull Zone cache","summary":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","description":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","kind":"script","risk":"critical","side_effects":["Removes all cached objects for the Pull Zone.","Sends subsequent requests to the origin until the cache re-warms.","Can cause an immediate origin-load and egress spike."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID whose complete cache will be purged.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Purge everything only after targeted purges are insufficient","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_tag","title":"Purge cache tag","summary":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","description":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","kind":"script","risk":"high","side_effects":["Removes every cached object carrying the tag in this Pull Zone.","Causes subsequent requests for matched objects to reach the origin."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"cache_tag","type":"string","required":true,"description":"Exact Bunny cache tag to purge.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,128}$","max_length":128}}],"examples":[{"title":"Purge one release tag","args":{"cache_tag":"release-2026-07-31","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_url","title":"Purge cached URL","summary":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","description":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute HTTPS CDN URL to purge. Query strings are sent to Bunny but removed from action output.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}},{"name":"async","type":"boolean","required":false,"default":false,"description":"Return after Bunny accepts the purge instead of waiting for completion."},{"name":"exact_path","type":"boolean","required":false,"default":false,"description":"When a URL ends in slash, purge only that exact path instead of a wildcard suffix."}],"examples":[{"title":"Purge one video","args":{"url":"https://cdn.example.com/video/intro.mp4"}}],"search_terms":[]},{"id":"bunny.remove_allowed_referrer","title":"Remove allowed referrer","summary":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","description":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and can block legitimate embeds."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to remove.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Remove one allowed site","args":{"hostname":"old.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_ip","title":"Remove blocked IP address","summary":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","description":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and unblock.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Unblock one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_referrer","title":"Remove blocked referrer","summary":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","description":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to unblock.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Unblock one site","args":{"hostname":"partner.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_hostname","title":"Remove Pull Zone hostname","summary":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","description":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","kind":"script","risk":"high","side_effects":["Detaches the custom hostname from the Pull Zone.","Interrupts CDN delivery through that hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to detach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Detach a hostname","args":{"hostname":"old-cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.safehop_statistics","title":"Get SafeHop statistics","summary":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","description":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"SafeHop metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_cache_behavior","title":"Change one Pull Zone cache behavior","summary":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","description":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","kind":"script","risk":"high","side_effects":["Changes one Pull Zone caching behavior immediately.","Can increase misses, serve stale objects, or alter query-string cache keys depending on the selected setting."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"setting","type":"string","required":true,"description":"Declared cache behavior to change.","validation":{"enum":["ignore_query_strings","cache_slice","smart_cache","cache_error_responses","background_update","stale_while_offline","stale_while_updating","request_coalescing","query_string_ordering"]}},{"name":"enabled","type":"boolean","required":true,"description":"New setting value."}],"examples":[{"title":"Serve stale cache while the origin is offline","args":{"enabled":true,"pull_zone_id":123456,"setting":"stale_while_offline"}}],"search_terms":[]},{"id":"bunny.set_cache_ttl","title":"Change Pull Zone cache TTLs","summary":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","description":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","kind":"script","risk":"high","side_effects":["Changes caching for subsequent responses on the Pull Zone.","Does not purge objects already stored at the edge or in browsers."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"edge_seconds","type":"string","required":false,"default":"unchanged","description":"Edge cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}},{"name":"browser_seconds","type":"string","required":false,"default":"unchanged","description":"Browser cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}}],"examples":[{"title":"Cache at edge for one day and in browsers for one hour","args":{"browser_seconds":"3600","edge_seconds":"86400","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_force_ssl","title":"Change hostname Force SSL","summary":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","description":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","kind":"script","risk":"high","side_effects":["Changes redirect and transport enforcement for one hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Attached Pull Zone hostname.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}},{"name":"enabled","type":"boolean","required":true,"description":"New Force SSL state."}],"examples":[{"title":"Force HTTPS","args":{"enabled":true,"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_logging","title":"Change Pull Zone logging","summary":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","description":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","kind":"script","risk":"medium","side_effects":["Changes whether Bunny records CDN requests for this Pull Zone.","Enforces IP anonymization and selects plain or JSON storage format."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New request-logging state."},{"name":"anonymization","type":"string","required":false,"default":"last_octet","description":"IP anonymization strength.","validation":{"enum":["last_octet","drop_all"]}},{"name":"format","type":"string","required":false,"default":"json","description":"Log storage format.","validation":{"enum":["plain","json"]}}],"examples":[{"title":"Enable anonymized JSON logs","args":{"enabled":true,"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin","title":"Change Pull Zone origin","summary":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","description":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","kind":"script","risk":"high","side_effects":["Subsequent cache misses and revalidations use the new origin.","Can change the Host header sent to the origin.","Can disable origin certificate verification when explicitly requested."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"origin_host_header","type":"string","required":false,"default":"","description":"Optional Host header sent to the origin; empty leaves it unchanged.","validation":{"pattern":"^(|[A-Za-z0-9][A-Za-z0-9.-]{0,252})$","max_length":253}},{"name":"verify_origin_ssl","type":"boolean","required":false,"default":true,"description":"Verify the origin TLS certificate. Keep enabled unless a separately approved exception requires otherwise."}],"examples":[{"title":"Move to a verified origin","args":{"origin_host_header":"new-origin.example.com","origin_url":"https://new-origin.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin_shield","title":"Change Pull Zone Origin Shield","summary":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","description":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","kind":"script","risk":"high","side_effects":["Changes whether cache misses pass through Origin Shield.","A supplied zone code changes the shield location.","Origin Shield pricing and latency may change."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New Origin Shield state."},{"name":"zone_code","type":"string","required":false,"default":"","description":"Optional Bunny region code from bunny.list_regions; empty leaves the location unchanged.","validation":{"pattern":"^(|[A-Za-z0-9-]{1,32})$","max_length":32}}],"examples":[{"title":"Enable Origin Shield in one region","args":{"enabled":true,"pull_zone_id":123456,"zone_code":"DE"}}],"search_terms":[]},{"id":"bunny.statistics","title":"Get CDN statistics","summary":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","description":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; empty uses Bunny's default window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"pull_zone_id","type":"integer","required":false,"default":0,"description":"Pull Zone ID, or 0 for account-wide statistics.","validation":{"min":0,"max":9007199254740991}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets and preserve exact hours."}],"examples":[{"title":"One Pull Zone over Bunny's default window","args":{"pull_zone_id":123456}}],"search_terms":[]}]},{"version":"0.1.1","content_hash":"sha256:24ca6f13b85a69e89ea1d92894e17a949b32ef76237931bb552c19c3ace72250","tarball_url":"https://registry.emisar.dev/v1/packs/bunnycdn/0.1.1/24ca6f13b85a69e89ea1d92894e17a949b32ef76237931bb552c19c3ace72250/pack.tar.gz","actions":[{"id":"bunny.add_allowed_referrer","title":"Add allowed referrer","summary":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","description":"Add a hostname to a Pull Zone's allowlist; once an allowlist is active, unmatched referrers can be denied and legitimate embeds may stop working.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy for the Pull Zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern accepted by Bunny.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Allow one site","args":{"hostname":"www.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_ip","title":"Add blocked IP address","summary":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","description":"Block one IPv4 or IPv6 address on a Pull Zone; requests from that address begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and block.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Block one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_blocked_referrer","title":"Add blocked referrer","summary":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","description":"Block one referrer hostname on a Pull Zone; matching embedded requests begin failing immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and denies matching traffic."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to block.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Block one site","args":{"hostname":"scraper.example","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.add_hostname","title":"Add Pull Zone hostname","summary":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","description":"Add a custom hostname to a Pull Zone; traffic for a correctly pointed DNS name can begin reaching this zone before TLS is forced.","kind":"script","risk":"high","side_effects":["Attaches a custom hostname to the Pull Zone.","Can begin serving traffic after DNS points at Bunny."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to attach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Attach a hostname","args":{"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.billing_usage","title":"Get CDN billing usage","summary":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","description":"Get a safe account charge and bandwidth projection plus current per-Pull-Zone usage, without payment-method or billing-identity fields.","kind":"script","risk":"low","side_effects":["Two read-only Core API requests."],"args":[],"examples":[{"title":"Account and Pull Zone usage","args":{}}],"search_terms":[]},{"id":"bunny.create_pull_zone","title":"Create Pull Zone","summary":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","description":"Create a billed Bunny CDN Pull Zone pointing at one HTTPS origin; traffic served through it begins consuming account bandwidth and balance.","kind":"script","risk":"high","side_effects":["Creates a persistent, billable Pull Zone.","Makes a new Bunny system hostname available for CDN traffic.","Enables anonymized logging when requested."],"args":[{"name":"name","type":"string","required":true,"description":"Account-unique Pull Zone name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$","max_length":64}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"tier","type":"string","required":false,"default":"premium","description":"Bunny Pull Zone traffic tier.","validation":{"enum":["premium","volume"]}},{"name":"enable_logging","type":"boolean","required":false,"default":true,"description":"Enable anonymized CDN request logging."},{"name":"enable_cache_slice","type":"boolean","required":false,"default":false,"description":"Enable cache slicing for large files and video."}],"examples":[{"title":"Create a logged video Pull Zone","args":{"enable_cache_slice":true,"name":"example-videos","origin_url":"https://origin.example.com/videos"}}],"search_terms":[]},{"id":"bunny.delete_pull_zone","title":"Delete Pull Zone","summary":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","description":"Delete a Pull Zone permanently; every Bunny hostname and custom hostname on that zone stops serving immediately and the operation cannot be undone.","kind":"script","risk":"critical","side_effects":["Permanently deletes the Pull Zone and its configuration.","Stops CDN delivery for every hostname attached to the zone."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID to delete.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Permanently delete a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.get_pull_zone","title":"Get Pull Zone","summary":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","description":"Show one Pull Zone's configuration and current monthly usage without credential or certificate fields.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Inspect a Pull Zone","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.list_pull_zones","title":"List Pull Zones","summary":"List one bounded page of Pull Zones accessible to the account API key.","description":"List one bounded page of Pull Zones accessible to the account API key.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"search","type":"string","required":false,"default":"","description":"Optional name search.","validation":{"pattern":"^[ -~]*$","max_length":128}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Pull Zones returned in this page.","validation":{"min":5,"max":1000}}],"examples":[{"title":"First page","args":{}}],"search_terms":[]},{"id":"bunny.list_regions","title":"List Bunny regions","summary":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","description":"List bunny.net regions and codes used by Pull Zone delivery and Origin Shield settings.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[],"examples":[{"title":"Regions","args":{}}],"search_terms":[]},{"id":"bunny.log_usage_summary","title":"Summarize CDN log usage","summary":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","description":"Summarize one bounded Logging API v2 page by sanitized path, cache status, status code, request count, and bytes sent. No client IP, user-agent, referrer, authorization header, or URL query string is returned.","kind":"script","risk":"low","side_effects":["One read-only CDN Logging API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":1000,"description":"Maximum log entries aggregated in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order before aggregation.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Attribute bytes by path and cache state","args":{"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.logs","title":"Fetch CDN request logs","summary":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","description":"Fetch one bounded, filterable page from CDN Logging API v2. The result can contain client IP, user-agent, and referrer metadata, so policy should limit who may retrieve it; authorization fields and URL query strings are removed.","kind":"script","risk":"medium","side_effects":["One CDN Logging API request.","Returns request-level client metadata into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID with logging enabled.","validation":{"min":1,"max":9007199254740991}},{"name":"from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; must be within Bunny's three-day retention window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"status","type":"string","required":false,"default":"","description":"Optional comma-separated HTTP codes or classes, such as 404,5xx.","validation":{"pattern":"^(|[1-5]([0-9]{2}|xx)(,[1-5]([0-9]{2}|xx)){0,8})$","max_length":35}},{"name":"cache_status","type":"string","required":false,"default":"","description":"Optional comma-separated cache statuses, such as HIT,MISS,STALE.","validation":{"pattern":"^(|[A-Z-]{1,16}(,[A-Z-]{1,16}){0,8})$","max_length":80}},{"name":"url_contains","type":"string","required":false,"default":"","description":"Optional case-insensitive substring filter over host and path.","validation":{"pattern":"^[ -~]*$","max_length":256}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum log entries in this page.","validation":{"min":1,"max":1000}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Entries to skip for pagination.","validation":{"min":0,"max":1000000}},{"name":"order","type":"string","required":false,"default":"desc","description":"Timestamp order.","validation":{"enum":["asc","desc"]}},{"name":"include_origin_shield","type":"boolean","required":false,"default":false,"description":"Include edge-to-shield requests."}],"examples":[{"title":"Recent cache misses for video paths","args":{"cache_status":"MISS","limit":100,"pull_zone_id":123456,"url_contains":"/video/"}}],"search_terms":[]},{"id":"bunny.optimizer_statistics","title":"Get Optimizer statistics","summary":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","description":"Get optimized request, traffic-saved, compression, and processing-time statistics for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Optimizer metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_errors","title":"Get origin error logs","summary":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","description":"Get one day's failed-origin records for a Pull Zone. The result can contain origin request paths and failure detail, so policy should limit who may retrieve it; query strings and arbitrary embedded log fields are removed.","kind":"script","risk":"medium","side_effects":["One read-only Origin Errors API request.","Returns origin failure detail into the governed run result and audit trail."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date","type":"string","required":true,"description":"UTC date in MM-DD-YYYY format.","validation":{"pattern":"^[0-9]{2}-[0-9]{2}-20[0-9]{2}$","max_length":10}}],"examples":[{"title":"Origin failures for one UTC day","args":{"date":"07-31-2026","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.origin_shield_statistics","title":"Get Origin Shield queue statistics","summary":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","description":"Get concurrent and queued Origin Shield request charts for one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"Origin Shield queue","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_all_cache","title":"Purge entire Pull Zone cache","summary":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","description":"Purge the entire Pull Zone cache; every object becomes cold at once and a busy zone can overwhelm or sharply increase traffic to its origin.","kind":"script","risk":"critical","side_effects":["Removes all cached objects for the Pull Zone.","Sends subsequent requests to the origin until the cache re-warms.","Can cause an immediate origin-load and egress spike."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID whose complete cache will be purged.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Purge everything only after targeted purges are insufficient","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_tag","title":"Purge cache tag","summary":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","description":"Purge every cached object carrying one tag in a Pull Zone; all matched objects become misses and can create a concentrated origin-load spike.","kind":"script","risk":"high","side_effects":["Removes every cached object carrying the tag in this Pull Zone.","Causes subsequent requests for matched objects to reach the origin."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"cache_tag","type":"string","required":true,"description":"Exact Bunny cache tag to purge.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,128}$","max_length":128}}],"examples":[{"title":"Purge one release tag","args":{"cache_tag":"release-2026-07-31","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.purge_url","title":"Purge cached URL","summary":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","description":"Purge one URL from Bunny's edge cache; the next request for each removed variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute HTTPS CDN URL to purge. Query strings are sent to Bunny but removed from action output.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}},{"name":"async","type":"boolean","required":false,"default":false,"description":"Return after Bunny accepts the purge instead of waiting for completion."},{"name":"exact_path","type":"boolean","required":false,"default":false,"description":"When a URL ends in slash, purge only that exact path instead of a wildcard suffix."}],"examples":[{"title":"Purge one video","args":{"url":"https://cdn.example.com/video/intro.mp4"}}],"search_terms":[]},{"id":"bunny.remove_allowed_referrer","title":"Remove allowed referrer","summary":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","description":"Remove a hostname from a Pull Zone's allowlist; clients referred by it can be denied immediately.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and can block legitimate embeds."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to remove.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Remove one allowed site","args":{"hostname":"old.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_ip","title":"Remove blocked IP address","summary":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","description":"Remove one IPv4 or IPv6 address from a Pull Zone blocklist; requests from that address can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes Pull Zone access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"address","type":"string","required":true,"description":"IPv4 or IPv6 address for Bunny to validate and unblock.","validation":{"pattern":"^[0-9A-Fa-f:.]{2,45}$","max_length":45}}],"examples":[{"title":"Unblock one address","args":{"address":"192.0.2.10","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_blocked_referrer","title":"Remove blocked referrer","summary":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","description":"Remove one referrer hostname from a Pull Zone blocklist; matching external embeds can resume consuming CDN bandwidth.","kind":"script","risk":"high","side_effects":["Changes hotlink-access policy and allows matching traffic again."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Referrer hostname or wildcard pattern to unblock.","validation":{"pattern":"^[A-Za-z0-9*][A-Za-z0-9.*-]{0,252}$","max_length":253}}],"examples":[{"title":"Unblock one site","args":{"hostname":"partner.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.remove_hostname","title":"Remove Pull Zone hostname","summary":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","description":"Remove a custom hostname from a Pull Zone; requests to that hostname stop being served by the zone immediately.","kind":"script","risk":"high","side_effects":["Detaches the custom hostname from the Pull Zone.","Interrupts CDN delivery through that hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"DNS hostname to detach.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}}],"examples":[{"title":"Detach a hostname","args":{"hostname":"old-cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.safehop_statistics","title":"Get SafeHop statistics","summary":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","description":"Get retried and saved request statistics for Bunny SafeHop on one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets."}],"examples":[{"title":"SafeHop metrics","args":{"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_cache_behavior","title":"Change one Pull Zone cache behavior","summary":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","description":"Enable or disable one declared cache behavior; the choice can change cache keys, freshness, origin load, or the traffic served while an origin is unhealthy.","kind":"script","risk":"high","side_effects":["Changes one Pull Zone caching behavior immediately.","Can increase misses, serve stale objects, or alter query-string cache keys depending on the selected setting."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"setting","type":"string","required":true,"description":"Declared cache behavior to change.","validation":{"enum":["ignore_query_strings","cache_slice","smart_cache","cache_error_responses","background_update","stale_while_offline","stale_while_updating","request_coalescing","query_string_ordering"]}},{"name":"enabled","type":"boolean","required":true,"description":"New setting value."}],"examples":[{"title":"Serve stale cache while the origin is offline","args":{"enabled":true,"pull_zone_id":123456,"setting":"stale_while_offline"}}],"search_terms":[]},{"id":"bunny.set_cache_ttl","title":"Change Pull Zone cache TTLs","summary":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","description":"Change edge or browser cache TTL overrides; shorter values increase origin traffic while longer values can keep stale content in circulation.","kind":"script","risk":"high","side_effects":["Changes caching for subsequent responses on the Pull Zone.","Does not purge objects already stored at the edge or in browsers."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"edge_seconds","type":"string","required":false,"default":"unchanged","description":"Edge cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}},{"name":"browser_seconds","type":"string","required":false,"default":"unchanged","description":"Browser cache override in seconds, or unchanged.","validation":{"pattern":"^(unchanged|[0-9]{1,9})$","max_length":9}}],"examples":[{"title":"Cache at edge for one day and in browsers for one hour","args":{"browser_seconds":"3600","edge_seconds":"86400","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_force_ssl","title":"Change hostname Force SSL","summary":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","description":"Enable or disable HTTP-to-HTTPS enforcement for one Pull Zone hostname; disabling permits unencrypted client requests where Bunny accepts them.","kind":"script","risk":"high","side_effects":["Changes redirect and transport enforcement for one hostname."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"hostname","type":"string","required":true,"description":"Attached Pull Zone hostname.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$","max_length":253}},{"name":"enabled","type":"boolean","required":true,"description":"New Force SSL state."}],"examples":[{"title":"Force HTTPS","args":{"enabled":true,"hostname":"cdn.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_logging","title":"Change Pull Zone logging","summary":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","description":"Enable or disable request logging with enforced IP anonymization; enabling stores request metadata for Bunny's retention window and disabling removes incident visibility.","kind":"script","risk":"medium","side_effects":["Changes whether Bunny records CDN requests for this Pull Zone.","Enforces IP anonymization and selects plain or JSON storage format."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New request-logging state."},{"name":"anonymization","type":"string","required":false,"default":"last_octet","description":"IP anonymization strength.","validation":{"enum":["last_octet","drop_all"]}},{"name":"format","type":"string","required":false,"default":"json","description":"Log storage format.","validation":{"enum":["plain","json"]}}],"examples":[{"title":"Enable anonymized JSON logs","args":{"enabled":true,"pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin","title":"Change Pull Zone origin","summary":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","description":"Change where a Pull Zone fetches content; a wrong URL, host header, or TLS choice can redirect traffic, expose requests, or take the zone offline.","kind":"script","risk":"high","side_effects":["Subsequent cache misses and revalidations use the new origin.","Can change the Host header sent to the origin.","Can disable origin certificate verification when explicitly requested."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"origin_url","type":"string","required":true,"description":"HTTPS origin URL without user-info credentials or a query string.","validation":{"pattern":"^https://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?(/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*)?$","max_length":2048}},{"name":"origin_host_header","type":"string","required":false,"default":"","description":"Optional Host header sent to the origin; empty leaves it unchanged.","validation":{"pattern":"^(|[A-Za-z0-9][A-Za-z0-9.-]{0,252})$","max_length":253}},{"name":"verify_origin_ssl","type":"boolean","required":false,"default":true,"description":"Verify the origin TLS certificate. Keep enabled unless a separately approved exception requires otherwise."}],"examples":[{"title":"Move to a verified origin","args":{"origin_host_header":"new-origin.example.com","origin_url":"https://new-origin.example.com","pull_zone_id":123456}}],"search_terms":[]},{"id":"bunny.set_origin_shield","title":"Change Pull Zone Origin Shield","summary":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","description":"Enable, disable, or relocate Origin Shield; this changes the origin request path, latency, and billable shield traffic for the Pull Zone.","kind":"script","risk":"high","side_effects":["Changes whether cache misses pass through Origin Shield.","A supplied zone code changes the shield location.","Origin Shield pricing and latency may change."],"args":[{"name":"pull_zone_id","type":"integer","required":true,"description":"Pull Zone ID.","validation":{"min":1,"max":9007199254740991}},{"name":"enabled","type":"boolean","required":true,"description":"New Origin Shield state."},{"name":"zone_code","type":"string","required":false,"default":"","description":"Optional Bunny region code from bunny.list_regions; empty leaves the location unchanged.","validation":{"pattern":"^(|[A-Za-z0-9-]{1,32})$","max_length":32}}],"examples":[{"title":"Enable Origin Shield in one region","args":{"enabled":true,"pull_zone_id":123456,"zone_code":"DE"}}],"search_terms":[]},{"id":"bunny.statistics","title":"Get CDN statistics","summary":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","description":"Get bandwidth, requests, cache hit rate, origin traffic, response-time, error, and geographic statistics for the account or one Pull Zone.","kind":"script","risk":"low","side_effects":["One read-only Core API request."],"args":[{"name":"date_from","type":"string","required":false,"default":"","description":"Optional inclusive UTC start in RFC3339 seconds; empty uses Bunny's default window.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"date_to","type":"string","required":false,"default":"","description":"Optional exclusive UTC end in RFC3339 seconds.","validation":{"pattern":"^(|20[0-9]{2}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z)$","max_length":20}},{"name":"pull_zone_id","type":"integer","required":false,"default":0,"description":"Pull Zone ID, or 0 for account-wide statistics.","validation":{"min":0,"max":9007199254740991}},{"name":"hourly","type":"boolean","required":false,"default":false,"description":"Return hourly chart buckets and preserve exact hours."}],"examples":[{"title":"One Pull Zone over Bunny's default window","args":{"pull_zone_id":123456}}],"search_terms":[]}]}]},{"id":"caddy","name":"Caddy web server","version":"0.1.24","description":"Caddy v2 ops via its admin API (default http://127.0.0.1:2019) and CLI. Config dump, upstream health, PKI inventory, config validation, plus reload (live config swap). Set CADDY_ADMIN env var if not on default.","vendor":"emisar","homepage":"https://emisar.dev/packs/caddy","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/caddy","content_hash":"sha256:da195b544d166f93d5e7faebc0695d2bcd8c77badda1398e7d2608647ac7626b","tarball_url":"https://registry.emisar.dev/v1/packs/caddy/0.1.24/da195b544d166f93d5e7faebc0695d2bcd8c77badda1398e7d2608647ac7626b/pack.tar.gz","requires":{"os":["linux"],"binaries":["caddy","curl"]},"detect":{"binaries":[],"processes":["caddy"],"ports":[2019]},"setup":{"summary":"Operates on the local Caddy instance on the runner host — no credentials needed. Inventory/health actions curl the admin API at 127.0.0.1:2019; validate/reload/stop run the caddy binary directly.","env":[{"name":"CADDY_ADMIN","description":"Base URL of the Caddy admin API; set only if it does not listen on the default.","default":"http://127.0.0.1:2019"},{"name":"CADDY_ACCESS_LOG","description":"Path to the Caddy access log for access_log_tail.","default":"/var/log/caddy/access.log"}],"notes":["`CADDY_ADMIN` and `CADDY_ACCESS_LOG` only reach an action when the runner allowlists them in `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default. Unset, both fall back to their defaults above, so a non-default admin endpoint or log path silently reads the local one instead of yours."],"host_access":[{"actions":["caddy.access_log_tail","caddy.adapt_caddyfile","caddy.validate_config","caddy.reload_config"],"requirement":"Read Caddy's protected log and configuration files. Reload also requires the separately configured admin endpoint to accept the request.","recipes":[{"name":"Add the Emisar service user to caddy","commands":["sudo usermod -aG caddy emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx caddy","sudo -u emisar test -r /etc/caddy/Caddyfile"],"impact":"Every process running as emisar can read files exposed to the caddy group. Reload can replace the live server configuration when the admin endpoint also permits it."}]}],"verify":"caddy.version"},"actions":[{"id":"caddy.access_log_tail","title":"tail caddy access log","summary":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","description":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":["recent requests"],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${CADDY_ACCESS_LOG:-/var/log/caddy/access.log}\""]}},{"id":"caddy.adapt_caddyfile","title":"caddy adapt --config <file>","summary":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","description":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","kind":"exec","risk":"high","side_effects":["One forked process.","Read-only, but emits the full adapted config (may include secrets)."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Caddyfile path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Adapt the default Caddyfile","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["adapt","--config","{{ args.file }}","--pretty"]}},{"id":"caddy.config_dump","title":"GET /config (current config)","summary":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full Caddy config (may include secrets)."],"args":[],"examples":[{"title":"Live config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/config/\""]}},{"id":"caddy.pki_certs","title":"GET /pki/ca/<id>/certificates","summary":"List certificates managed by Caddy's internal PKI.","description":"List certificates managed by Caddy's internal PKI.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"ca","type":"string","required":false,"default":"local","description":"CA ID.","validation":{"pattern":"^[a-z0-9_\\-]{1,32}$"}}],"examples":[{"title":"Local CA certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/pki/ca/${1}/certificates\"","emisar","{{ args.ca }}"]}},{"id":"caddy.reload_config","title":"caddy reload --config <file>","summary":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","description":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","kind":"exec","risk":"high","side_effects":["Replaces the in-memory config atomically.","Existing connections keep running on their handlers."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Reload","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["reload","--config","{{ args.file }}"]}},{"id":"caddy.reverse_proxy_upstreams","title":"GET /reverse_proxy/upstreams","summary":"List all reverse-proxy upstreams with current health.","description":"List all reverse-proxy upstreams with current health.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Upstream health","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/reverse_proxy/upstreams\""]}},{"id":"caddy.runtime_metrics","title":"GET /metrics (Prometheus exposition)","summary":"Show Caddy's Prometheus-format metrics endpoint.","description":"Show Caddy's Prometheus-format metrics endpoint.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/metrics\""]}},{"id":"caddy.stop","title":"caddy stop","summary":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","description":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","kind":"exec","risk":"high","side_effects":["All Caddy listeners closed.","In-flight requests drain then terminate.","Reverse-proxy traffic to backends stops.","Process exits; supervisor decides restart."],"args":[],"examples":[{"title":"Stop Caddy","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https -X POST \"${CADDY_ADMIN:-http://127.0.0.1:2019}/stop\""]}},{"id":"caddy.validate_config","title":"caddy validate --config <file>","summary":"Validate a Caddyfile or JSON config without loading it.","description":"Validate a Caddyfile or JSON config without loading it.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Validate","args":{}}],"search_terms":["syntax errors"],"command":{"binary":"caddy","argv":["validate","--config","{{ args.file }}"]}},{"id":"caddy.version","title":"caddy version","summary":"Show Caddy binary version + build info.","description":"Show Caddy binary version + build info.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["version"]}}],"previous_versions":[{"version":"0.1.21","content_hash":"sha256:beff159064a16a07edbb51a0e775ab63377461473281630eed55b993a0b1be13","tarball_url":"https://registry.emisar.dev/v1/packs/caddy/0.1.21/beff159064a16a07edbb51a0e775ab63377461473281630eed55b993a0b1be13/pack.tar.gz","actions":[{"id":"caddy.access_log_tail","title":"tail caddy access log","summary":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","description":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":["recent requests"],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${CADDY_ACCESS_LOG:-/var/log/caddy/access.log}\""]}},{"id":"caddy.adapt_caddyfile","title":"caddy adapt --config <file>","summary":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","description":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","kind":"exec","risk":"high","side_effects":["One forked process.","Read-only, but emits the full adapted config (may include secrets)."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Caddyfile path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Adapt the default Caddyfile","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["adapt","--config","{{ args.file }}","--pretty"]}},{"id":"caddy.config_dump","title":"GET /config (current config)","summary":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full Caddy config (may include secrets)."],"args":[],"examples":[{"title":"Live config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/config/\""]}},{"id":"caddy.pki_certs","title":"GET /pki/ca/<id>/certificates","summary":"List certificates managed by Caddy's internal PKI.","description":"List certificates managed by Caddy's internal PKI.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"ca","type":"string","required":false,"default":"local","description":"CA ID.","validation":{"pattern":"^[a-z0-9_\\-]{1,32}$"}}],"examples":[{"title":"Local CA certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/pki/ca/${1}/certificates\"","emisar","{{ args.ca }}"]}},{"id":"caddy.reload_config","title":"caddy reload --config <file>","summary":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","description":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","kind":"exec","risk":"high","side_effects":["Replaces the in-memory config atomically.","Existing connections keep running on their handlers."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Reload","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["reload","--config","{{ args.file }}"]}},{"id":"caddy.reverse_proxy_upstreams","title":"GET /reverse_proxy/upstreams","summary":"List all reverse-proxy upstreams with current health.","description":"List all reverse-proxy upstreams with current health.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Upstream health","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/reverse_proxy/upstreams\""]}},{"id":"caddy.runtime_metrics","title":"GET /metrics (Prometheus exposition)","summary":"Show Caddy's Prometheus-format metrics endpoint.","description":"Show Caddy's Prometheus-format metrics endpoint.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/metrics\""]}},{"id":"caddy.stop","title":"caddy stop","summary":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","description":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","kind":"exec","risk":"high","side_effects":["All Caddy listeners closed.","In-flight requests drain then terminate.","Reverse-proxy traffic to backends stops.","Process exits; supervisor decides restart."],"args":[],"examples":[{"title":"Stop Caddy","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${CADDY_ADMIN:-http://127.0.0.1:2019}/stop\""]}},{"id":"caddy.validate_config","title":"caddy validate --config <file>","summary":"Validate a Caddyfile or JSON config without loading it.","description":"Validate a Caddyfile or JSON config without loading it.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Validate","args":{}}],"search_terms":["syntax errors"],"command":{"binary":"caddy","argv":["validate","--config","{{ args.file }}"]}},{"id":"caddy.version","title":"caddy version","summary":"Show Caddy binary version + build info.","description":"Show Caddy binary version + build info.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["version"]}}]},{"version":"0.1.19","content_hash":"sha256:2e79fd12f07396c637caddacc5645520d39a4cec3e790012684b09bc22747edd","tarball_url":"https://registry.emisar.dev/v1/packs/caddy/0.1.19/2e79fd12f07396c637caddacc5645520d39a4cec3e790012684b09bc22747edd/pack.tar.gz","actions":[{"id":"caddy.access_log_tail","title":"tail caddy access log","summary":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","description":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":["recent requests"],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${CADDY_ACCESS_LOG:-/var/log/caddy/access.log}\""]}},{"id":"caddy.adapt_caddyfile","title":"caddy adapt --config <file>","summary":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","description":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","kind":"exec","risk":"high","side_effects":["One forked process.","Read-only, but emits the full adapted config (may include secrets)."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Caddyfile path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Adapt the default Caddyfile","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["adapt","--config","{{ args.file }}","--pretty"]}},{"id":"caddy.config_dump","title":"GET /config (current config)","summary":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full Caddy config (may include secrets)."],"args":[],"examples":[{"title":"Live config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/config/\""]}},{"id":"caddy.pki_certs","title":"GET /pki/ca/<id>/certificates","summary":"List certificates managed by Caddy's internal PKI.","description":"List certificates managed by Caddy's internal PKI.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"ca","type":"string","required":false,"default":"local","description":"CA ID.","validation":{"pattern":"^[a-z0-9_\\-]{1,32}$"}}],"examples":[{"title":"Local CA certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/pki/ca/${1}/certificates\"","emisar","{{ args.ca }}"]}},{"id":"caddy.reload_config","title":"caddy reload --config <file>","summary":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","description":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","kind":"exec","risk":"high","side_effects":["Replaces the in-memory config atomically.","Existing connections keep running on their handlers."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Reload","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["reload","--config","{{ args.file }}"]}},{"id":"caddy.reverse_proxy_upstreams","title":"GET /reverse_proxy/upstreams","summary":"List all reverse-proxy upstreams with current health.","description":"List all reverse-proxy upstreams with current health.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Upstream health","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/reverse_proxy/upstreams\""]}},{"id":"caddy.runtime_metrics","title":"GET /metrics (Prometheus exposition)","summary":"Show Caddy's Prometheus-format metrics endpoint.","description":"Show Caddy's Prometheus-format metrics endpoint.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/metrics\""]}},{"id":"caddy.stop","title":"caddy stop","summary":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","description":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","kind":"exec","risk":"high","side_effects":["All Caddy listeners closed.","In-flight requests drain then terminate.","Reverse-proxy traffic to backends stops.","Process exits; supervisor decides restart."],"args":[],"examples":[{"title":"Stop Caddy","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${CADDY_ADMIN:-http://127.0.0.1:2019}/stop\""]}},{"id":"caddy.validate_config","title":"caddy validate --config <file>","summary":"Validate a Caddyfile or JSON config without loading it.","description":"Validate a Caddyfile or JSON config without loading it.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Validate","args":{}}],"search_terms":["syntax errors"],"command":{"binary":"caddy","argv":["validate","--config","{{ args.file }}"]}},{"id":"caddy.version","title":"caddy version","summary":"Show Caddy binary version + build info.","description":"Show Caddy binary version + build info.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["version"]}}]},{"version":"0.1.18","content_hash":"sha256:83a925d9b7ea9f73f76b17da58e6ace9fbb845baa074c7622352cae3aadfa8fb","tarball_url":"https://registry.emisar.dev/v1/packs/caddy/0.1.18/83a925d9b7ea9f73f76b17da58e6ace9fbb845baa074c7622352cae3aadfa8fb/pack.tar.gz","actions":[{"id":"caddy.access_log_tail","title":"tail caddy access log","summary":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","description":"Tail the access log (path configurable via CADDY_ACCESS_LOG env).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":["recent requests"],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${CADDY_ACCESS_LOG:-/var/log/caddy/access.log}\""]}},{"id":"caddy.adapt_caddyfile","title":"caddy adapt --config <file>","summary":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","description":"Convert a Caddyfile to JSON config without loading it. The output is the full resulting config — the same content class as `caddy.config_dump` — and can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens); adapt errors also quote offending Caddyfile lines back. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret.","kind":"exec","risk":"high","side_effects":["One forked process.","Read-only, but emits the full adapted config (may include secrets)."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Caddyfile path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Adapt the default Caddyfile","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["adapt","--config","{{ args.file }}","--pretty"]}},{"id":"caddy.config_dump","title":"GET /config (current config)","summary":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the currently-loaded Caddy configuration as JSON. This surfaces the full config, which can carry secrets (TLS private-key material, basic-auth hashes, upstream credentials, API tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full Caddy config (may include secrets)."],"args":[],"examples":[{"title":"Live config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/config/\""]}},{"id":"caddy.pki_certs","title":"GET /pki/ca/<id>/certificates","summary":"List certificates managed by Caddy's internal PKI.","description":"List certificates managed by Caddy's internal PKI.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"ca","type":"string","required":false,"default":"local","description":"CA ID.","validation":{"pattern":"^[a-z0-9_\\-]{1,32}$"}}],"examples":[{"title":"Local CA certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/pki/ca/${1}/certificates\"","emisar","{{ args.ca }}"]}},{"id":"caddy.reload_config","title":"caddy reload --config <file>","summary":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","description":"Live-swap the running config. No connection drops on success; rejected config keeps the old one running.","kind":"exec","risk":"high","side_effects":["Replaces the in-memory config atomically.","Existing connections keep running on their handlers."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Reload","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["reload","--config","{{ args.file }}"]}},{"id":"caddy.reverse_proxy_upstreams","title":"GET /reverse_proxy/upstreams","summary":"List all reverse-proxy upstreams with current health.","description":"List all reverse-proxy upstreams with current health.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Upstream health","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/reverse_proxy/upstreams\""]}},{"id":"caddy.runtime_metrics","title":"GET /metrics (Prometheus exposition)","summary":"Show Caddy's Prometheus-format metrics endpoint.","description":"Show Caddy's Prometheus-format metrics endpoint.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${CADDY_ADMIN:-http://127.0.0.1:2019}/metrics\""]}},{"id":"caddy.stop","title":"caddy stop","summary":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","description":"Stop the running Caddy process via its admin API. All listeners close; in-flight requests drain. Recovery requires starting Caddy again via systemd or `caddy start`. Use as a last resort during incidents.","kind":"exec","risk":"high","side_effects":["All Caddy listeners closed.","In-flight requests drain then terminate.","Reverse-proxy traffic to backends stops.","Process exits; supervisor decides restart."],"args":[],"examples":[{"title":"Stop Caddy","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${CADDY_ADMIN:-http://127.0.0.1:2019}/stop\""]}},{"id":"caddy.validate_config","title":"caddy validate --config <file>","summary":"Validate a Caddyfile or JSON config without loading it.","description":"Validate a Caddyfile or JSON config without loading it.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[{"name":"file","type":"string","required":false,"default":"/etc/caddy/Caddyfile","description":"Config path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/etc/caddy","/srv","/opt"]}}],"examples":[{"title":"Validate","args":{}}],"search_terms":["syntax errors"],"command":{"binary":"caddy","argv":["validate","--config","{{ args.file }}"]}},{"id":"caddy.version","title":"caddy version","summary":"Show Caddy binary version + build info.","description":"Show Caddy binary version + build info.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"caddy","argv":["version"]}}]}],"retired_below":"0.1.16"},{"id":"cassandra","name":"Cassandra operations","version":"0.6.4","description":"Deep Cassandra ops via nodetool + cqlsh: topology (status, ring, gossip, describering, failure detector), health (tpstats, netstats, proxy + table histograms, compaction stats + history, GC, clients, hot and large partitions, tombstones), schema introspection down to one table, effective runtime configuration, approval-gated data reads, runtime limits a running node accepts without a restart (stream and inter-datacenter throughput, compaction, hints, batchlog replay, snapshots, request timeouts, caches, stage concurrency, tracing), switches for compaction, hints, and backup, maintenance mutators (snapshot, flush, cleanup, verify, compact, scrub, garbage collect, upgrade + relocate SSTables, cache invalidation), repair workflows, node lifecycle (drain, decommission, assassinate, removenode, rebuild, bootstrap resume), default-denied native transport and gossip switches, and logging level control. JMX on 127.0.0.1:7199.","vendor":"emisar","homepage":"https://emisar.dev/packs/cassandra","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/cassandra","content_hash":"sha256:5733af7e5b44a25ebfd277e6f14bae7612ecf3c11544f74dd406e445bdec3a8a","tarball_url":"https://registry.emisar.dev/v1/packs/cassandra/0.6.4/5733af7e5b44a25ebfd277e6f14bae7612ecf3c11544f74dd406e445bdec3a8a/pack.tar.gz","requires":{"os":["linux"],"binaries":["nodetool","bash"]},"detect":{"binaries":["nodetool","cqlsh"],"processes":["CassandraDaemon"],"ports":[9042]},"setup":{"summary":"nodetool actions connect to the local node's JMX port (127.0.0.1:7199 by default, set per call) and take no credentials. cqlsh actions read `CQLSH_HOST` and `CQLSH_PORT` on the runner host (defaulting to 127.0.0.1:9042) and authenticate, when the cluster requires it, from `~/.cassandra/cqlshrc`.","env":[{"name":"CQLSH_HOST","description":"Host for the cqlsh actions (schema/keyspace/role introspection).","default":"127.0.0.1"},{"name":"CQLSH_PORT","description":"Native CQL port for the cqlsh actions.","default":"9042"}],"notes":["nodetool host/port come from each action's args (default 127.0.0.1:7199), not the environment; this pack passes no JMX username/password, so it works only against a node without JMX auth.","cqlsh credentials belong in `~/.cassandra/cqlshrc` (with a [authentication] username/password) on the runner host — read from disk, so it needs no `inherit_env` entry; the actions pass no -u/-p.","Lifecycle and maintenance mutators (repair, drain, decommission, assassinate, removenode, cleanup, compact) are cluster-affecting; run the read actions first.","The runtime limit actions change one node and take effect at once, but a restart returns it to cassandra.yaml — after any node restart, read the limits back and set them again."],"host_access":[{"actions":["cassandra.analyze_disk_pressure"],"requirement":"Traverse Cassandra's service-owned data and commitlog directories.","recipes":[{"name":"Add the Emisar service user to cassandra","commands":["sudo usermod -aG cassandra emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx cassandra","sudo -u emisar test -r /var/lib/cassandra/data","sudo -u emisar test -x /var/lib/cassandra/data","sudo -u emisar test -r /var/lib/cassandra/commitlog","sudo -u emisar test -x /var/lib/cassandra/commitlog"],"impact":"Every process running as emisar can traverse files exposed to the cassandra group, including raw database and commitlog storage outside this aggregate size action."}]}],"verify":"cassandra.nodetool_status"},"actions":[{"id":"cassandra.analyze_disk_pressure","title":"Analyze Cassandra disk pressure","summary":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","description":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","kind":"script","risk":"low","side_effects":["Reads filesystem metadata (df, du counts).","Does not modify Cassandra data or configuration.","May create temporary files inside the runner's work directory."],"args":[{"name":"keyspace_filter","type":"string","required":false,"default":"","description":"Optional keyspace name to focus the analysis on.","validation":{"pattern":"^[a-zA-Z0-9_.*-]{0,80}$"}}],"examples":[{"title":"Analyze without keyspace filter","args":{}}],"search_terms":["disk full","running out of space"]},{"id":"cassandra.cqlsh_describe_keyspace","title":"cqlsh -e \"DESCRIBE KEYSPACE <ks>\"","summary":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","description":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace DDL","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACE '\"$1\"';' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_describe_schema","title":"cqlsh -e \"DESCRIBE SCHEMA\"","summary":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","description":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Full schema","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE SCHEMA;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_describe_table","title":"cqlsh -e \"DESCRIBE TABLE <ks>.<table>\"","summary":"Show the full DDL for one table — columns, primary key, and every table property (compaction, compression, gc_grace_seconds, caching, TTL defaults).","description":"Show the full DDL for one table — columns, primary key, and every table property (compaction, compression, gc_grace_seconds, caching, TTL defaults).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to describe.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table's DDL","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"DESCRIBE TABLE $1.$2;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.cqlsh_largest_partitions","title":"cqlsh -e \"SELECT * FROM system_views.max_partition_size\"","summary":"List each table's largest partition on this node, in mebibytes — the read that finds the wide partition behind slow reads, timeouts, or heap pressure.","description":"List each table's largest partition on this node, in mebibytes — the read that finds the wide partition behind slow reads, timeouts, or heap pressure.","kind":"exec","risk":"low","side_effects":["One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Largest partition per table","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, table_name, mebibytes FROM system_views.max_partition_size LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_list_keyspaces","title":"cqlsh -e \"DESCRIBE KEYSPACES\"","summary":"List all keyspaces.","description":"List all keyspaces.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Keyspaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_permissions","title":"cqlsh -e \"LIST ALL PERMISSIONS\"","summary":"List every permission granted to every role — who may read, write, or alter which keyspace and table. Needs CassandraAuthorizer and a login with permission to see other roles' grants.","description":"List every permission granted to every role — who may read, write, or alter which keyspace and table. Needs CassandraAuthorizer and a login with permission to see other roles' grants.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"All grants","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e 'LIST ALL PERMISSIONS;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_roles","title":"cqlsh -e \"LIST ROLES\"","summary":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","description":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Roles","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'LIST ROLES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_tables","title":"cqlsh -e \"SELECT table_name FROM system_schema.tables\"","summary":"List the tables in one keyspace by name — the cheap look-up before cassandra.cqlsh_describe_table, without the full DDL that cassandra.cqlsh_describe_keyspace dumps.","description":"List the tables in one keyspace by name — the cheap look-up before cassandra.cqlsh_describe_table, without the full DDL that cassandra.cqlsh_describe_keyspace dumps.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to list.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Tables in a keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT table_name FROM system_schema.tables WHERE keyspace_name = '$1';\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_repair_history","title":"cqlsh -e \"SELECT * FROM system_distributed.repair_history\"","summary":"List recent repair sessions the cluster recorded — keyspace, table, coordinator, start and finish time, and status. Shows what repaired and what failed, which cassandra.nodetool_repair's own output does not survive.","description":"List recent repair sessions the cluster recorded — keyspace, table, coordinator, start and finish time, and status. Shows what repaired and what failed, which cassandra.nodetool_repair's own output does not survive.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only.","A range scan of a cluster-wide table, bounded by the row limit."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Sessions to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent repair sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, columnfamily_name, coordinator, started_at, finished_at, status FROM system_distributed.repair_history LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_running_queries","title":"cqlsh -e \"SELECT * FROM system_views.queries\"","summary":"List the queries this node is executing right now, with how long each has been queued and running — the first look when a node is busy and nobody knows what it is doing. The query text includes literal values, so this returns application data and is approval-gated.","description":"List the queries this node is executing right now, with how long each has been queued and running — the first look when a node is busy and nobody knows what it is doing. The query text includes literal values, so this returns application data and is approval-gated.","kind":"exec","risk":"high","side_effects":["Query text includes the literals callers passed, so application data reaches the caller and the audit trail.","One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Queries to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"What this node is running now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT thread_id, queued_micros, running_micros, task FROM system_views.queries LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_select_by_key","title":"cqlsh -e \"SELECT * FROM <ks>.<table> WHERE <key> = <value>\"","summary":"Read the rows of one partition by its key — the \"does this row exist, and what does it hold\" lookup. Returns stored application data, so it is approval-gated. Use cassandra.nodetool_getendpoints for which replicas own the key without reading it.","description":"Read the rows of one partition by its key — the \"does this row exist, and what does it hold\" lookup. Returns stored application data, so it is approval-gated. Use cassandra.nodetool_getendpoints for which replicas own the key without reading it.","kind":"exec","risk":"high","side_effects":["Returns application data — whatever the partition holds reaches the caller and the audit trail.","A single-partition read on the coordinator, bounded by the row limit and the output cap.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key_column","type":"string","required":true,"description":"Partition key column to match.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key_value","type":"string","required":true,"description":"Key value, unquoted; the action quotes it according to key_type.","validation":{"pattern":"^[A-Za-z0-9._:+@-]{1,128}$","max_length":128}},{"name":"key_type","type":"string","required":false,"default":"text","description":"How to render the value in CQL — text quotes it, number and uuid pass it through bare.","validation":{"enum":["text","number","uuid"]}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Rows to return from the partition.","validation":{"min":1,"max":100}}],"examples":[{"title":"One partition by a text key","args":{"key_column":"match_id","key_value":"a41f2c7e","keyspace":"valorant_ks","table":"matches"}},{"title":"One partition by an integer key","args":{"key_column":"id","key_type":"number","key_value":"42","keyspace":"valorant_ks","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$KEY_TYPE\" in\n  text) predicate=\"$KEY_COLUMN = '$KEY_VALUE'\" ;;\n  number|uuid) predicate=\"$KEY_COLUMN = $KEY_VALUE\" ;;\n  *) printf 'unsupported key_type: %s\\n' \"$KEY_TYPE\" >&2; exit 2 ;;\nesac\nexec cqlsh -e \"SELECT * FROM $KEYSPACE.$TABLE WHERE $predicate LIMIT $LIMIT;\" \\\n  \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"\n"]}},{"id":"cassandra.cqlsh_select_rows","title":"cqlsh -e \"SELECT * FROM <ks>.<table> LIMIT <n>\"","summary":"Read a bounded sample of rows from one table. Returns stored application data, so it is approval-gated; use cassandra.cqlsh_select_by_key when you know the partition key, and cassandra.cqlsh_describe_table when you only need the shape.","description":"Read a bounded sample of rows from one table. Returns stored application data, so it is approval-gated; use cassandra.cqlsh_select_by_key when you know the partition key, and cassandra.cqlsh_describe_table when you only need the shape.","kind":"exec","risk":"high","side_effects":["Returns application data — whatever the table holds reaches the caller and the audit trail.","A range scan over the ring, bounded by the row limit and the output cap.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"limit","type":"integer","required":false,"default":10,"description":"Rows to return.","validation":{"min":1,"max":100}}],"examples":[{"title":"Ten rows from a table","args":{"keyspace":"valorant_ks","limit":10,"table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT * FROM $1.$2 LIMIT $3;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}","{{ args.table }}","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_settings","title":"cqlsh -e \"SELECT name, value FROM system_views.settings\"","summary":"Show the configuration this node is actually running, from the system_views.settings virtual table — cassandra.yaml as parsed at boot plus every runtime change made since. Pass a filter to narrow it to one area (compaction, stream, hinted_handoff); the unfiltered dump is over 500 rows.","description":"Show the configuration this node is actually running, from the system_views.settings virtual table — cassandra.yaml as parsed at boot plus every runtime change made since. Pass a filter to narrow it to one area (compaction, stream, hinted_handoff); the unfiltered dump is over 500 rows.","kind":"exec","risk":"medium","side_effects":["One CQL query against a virtual table; nothing is read from disk.","Read-only.","Cassandra 5.0 masks credential settings itself; on 4.x it returns keystore and truststore passwords in the clear, so this action redacts them on the way out."],"args":[{"name":"filter","type":"string","required":false,"default":"","description":"Case-insensitive substring of the setting name; empty returns every setting.","validation":{"pattern":"^[A-Za-z0-9_.]{0,64}$","max_length":64}}],"examples":[{"title":"Every runtime setting","args":{}},{"title":"Just the streaming settings","args":{"filter":"stream"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","settings=$(cqlsh -e 'SELECT name, value FROM system_views.settings;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\") || exit $?\n[ -z \"$FILTER\" ] && { printf '%s\\n' \"$settings\"; exit 0; }\nprintf '%s\\n' \"$settings\" | grep -F -i -e \"$FILTER\"\nmatched=$?\n[ \"$matched\" -eq 1 ] && { printf 'no setting name matched: %s\\n' \"$FILTER\"; exit 0; }\nexit \"$matched\"\n"]}},{"id":"cassandra.cqlsh_system_peers","title":"SELECT * FROM system.peers_v2","summary":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","description":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Peers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers_v2;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\" || cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_system_size_estimates","title":"SELECT * FROM system.size_estimates","summary":"Show per-table partition + size estimates from the gossiped size_estimates table.","description":"Show per-table partition + size estimates from the gossiped size_estimates table.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Size estimates","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT keyspace_name, table_name, range_start, range_end, mean_partition_size, partitions_count FROM system.size_estimates LIMIT 200;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_tombstones_per_read","title":"cqlsh -e \"SELECT * FROM system_views.tombstones_per_read\"","summary":"Show how many tombstones each table scans per read on this node (count, max, p50, p99) — the read that confirms a delete-heavy or TTL-heavy table is the reason queries are slow or failing.","description":"Show how many tombstones each table scans per read on this node (count, max, p50, p99) — the read that confirms a delete-heavy or TTL-heavy table is the reason queries are slow or failing.","kind":"exec","risk":"low","side_effects":["One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Tombstones scanned per read","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, table_name, count, max, p50th, p99th FROM system_views.tombstones_per_read LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.nodetool_assassinate","title":"nodetool assassinate <address>","summary":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","description":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","kind":"exec","risk":"critical","side_effects":["Node entry purged from gossip.","No data streaming — data that was on the node is gone.","Other replicas eventually catch up via repair."],"args":[{"name":"address","type":"string","required":true,"description":"IP address of the dead node.","validation":{"pattern":"^[0-9]{1,3}(\\.[0-9]{1,3}){3}$"}}],"examples":[{"title":"Remove permanently dead node","args":{"address":"10.0.0.42"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["assassinate","{{ args.address }}"]}},{"id":"cassandra.nodetool_bootstrap_resume","title":"nodetool bootstrap resume","summary":"Resume a bootstrap that failed part way, streaming only the ranges this node is still missing — the recovery when a joining node lost a stream and stopped short of joining the ring. Fails on a node that already finished bootstrapping.","description":"Resume a bootstrap that failed part way, streaming only the ranges this node is still missing — the recovery when a joining node lost a stream and stopped short of joining the ring. Fails on a node that already finished bootstrapping.","kind":"exec","risk":"high","side_effects":["Restarts streaming from the source replicas; expect sustained network and disk load until it completes.","Blocks until the bootstrap finishes or fails again.","The rate honours the caps set by cassandra.nodetool_setstreamthroughput and cassandra.nodetool_setinterdcstreamthroughput."],"args":[],"examples":[{"title":"Finish an interrupted bootstrap","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["bootstrap","resume"]}},{"id":"cassandra.nodetool_cleanup","title":"nodetool cleanup [ks]","summary":"Remove data no longer owned by this node (after a topology change). IO-heavy.","description":"Remove data no longer owned by this node (after a topology change). IO-heavy.","kind":"exec","risk":"high","side_effects":["SSTables rewritten without data that moved off this node.","Heavy IO + CPU; may take hours on large tables.","Free space requirement during cleanup."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Cleanup post-bootstrap","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool cleanup \"$1\"; else nodetool cleanup; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_clearsnapshot","title":"nodetool clearsnapshot -t <name>","summary":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","description":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","kind":"exec","risk":"high","side_effects":["Snapshot hard links removed.","Disk space reclaims as the underlying SSTables become orphaned."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag to delete.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Delete tag","args":{"tag":"old-backup"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clearsnapshot","-t","{{ args.tag }}"]}},{"id":"cassandra.nodetool_clientstats","title":"nodetool clientstats","summary":"List the clients connected to this node — count per user, driver, and protocol version. The read before cutting a node out of service, and the one that finds an old driver still talking to it.","description":"List the clients connected to this node — count per user, driver, and protocol version. The read before cutting a node out of service, and the one that finds an old driver still talking to it.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Connected clients","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clientstats"]}},{"id":"cassandra.nodetool_compact","title":"nodetool compact <ks> [table]","summary":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","description":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","kind":"exec","risk":"high","side_effects":["Heavy disk + CPU for the duration.","For STCS, creates one giant SSTable that is hard to compact later.","For LCS, may be fine."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Major-compact one table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool compact \"$2\" \"$1\"; else nodetool compact \"$2\"; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_compactionhistory","title":"nodetool compactionhistory","summary":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","description":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Recent compactions","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["compactionhistory"]}},{"id":"cassandra.nodetool_compactionstats","title":"Cassandra compaction statistics","summary":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","description":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect compaction backlog","args":{}}],"search_terms":["compactions backed up","compaction backlog","pending compactions"],"command":{"binary":"nodetool","argv":["compactionstats"]}},{"id":"cassandra.nodetool_datapaths","title":"nodetool datapaths","summary":"List the directories each table stores data in — the read that shows which disk a table actually lives on before you judge a full filesystem or a JBOD imbalance.","description":"List the directories each table stores data in — the read that shows which disk a table actually lives on before you judge a full filesystem or a JBOD imbalance.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Data directories per table","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["datapaths"]}},{"id":"cassandra.nodetool_decommission","title":"nodetool decommission","summary":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","description":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","kind":"exec","risk":"critical","side_effects":["All data streams to remaining replicas.","Heavy network + disk on this and peer nodes.","Node leaves the ring; tokens are reassigned.","Can take many hours on big datasets."],"args":[],"examples":[{"title":"Remove this node","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["decommission"]}},{"id":"cassandra.nodetool_describecluster","title":"nodetool describecluster","summary":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","description":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Cluster summary","args":{}}],"search_terms":["schema disagreement","schema mismatch"],"command":{"binary":"nodetool","argv":["describecluster"]}},{"id":"cassandra.nodetool_describering","title":"nodetool describering <keyspace>","summary":"Show token range → replica endpoint mapping for one keyspace.","description":"Show token range → replica endpoint mapping for one keyspace.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace's ring","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["describering","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_disableautocompaction","title":"nodetool disableautocompaction <keyspace> [table]","summary":"Stop automatic compaction for a keyspace or one table on this node — the usual move before a bulk load or a heavy backfill. Re-enable it with cassandra.nodetool_enableautocompaction as soon as the load is done.","description":"Stop automatic compaction for a keyspace or one table on this node — the usual move before a bulk load or a heavy backfill. Re-enable it with cassandra.nodetool_enableautocompaction as soon as the load is done.","kind":"exec","risk":"medium","side_effects":["New compactions stop being scheduled; compactions already running finish.","SSTable count and read latency grow for as long as it stays off, and disk use grows with them.","Runtime-only — a restart returns the node to automatic compaction."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to pause.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to pause; empty pauses every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Pause compaction on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disableautocompaction","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_disablebackup","title":"nodetool disablebackup","summary":"Stop incremental backup on this node — Cassandra stops hard-linking each new SSTable into the backups directory. Use when those links are filling the disk and the backup tooling is not clearing them.","description":"Stop incremental backup on this node — Cassandra stops hard-linking each new SSTable into the backups directory. Use when those links are filling the disk and the backup tooling is not clearing them.","kind":"exec","risk":"medium","side_effects":["New SSTables are no longer linked for backup, so incremental backups stop covering fresh data.","Links already created stay on disk.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[],"examples":[{"title":"Stop incremental backup","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablebackup"]}},{"id":"cassandra.nodetool_disablebinary","title":"nodetool disablebinary","summary":"Stop the native transport on this node — every CQL client is disconnected and no new client can connect to it. Gossip, streaming, and repair keep running, so the node stays a replica and keeps taking writes from its peers. Use to take one node out of client rotation without draining it.","description":"Stop the native transport on this node — every CQL client is disconnected and no new client can connect to it. Gossip, streaming, and repair keep running, so the node stays a replica and keeps taking writes from its peers. Use to take one node out of client rotation without draining it.","kind":"exec","risk":"critical","side_effects":["Connected clients are dropped and must reconnect elsewhere; a driver without other reachable nodes fails outright.","Requests this node was coordinating are lost, and the rest of the cluster carries its client load.","Reverse it with cassandra.nodetool_enablebinary; a restart also brings the transport back."],"args":[],"examples":[{"title":"Take this node out of client rotation","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablebinary"]}},{"id":"cassandra.nodetool_disablegossip","title":"nodetool disablegossip","summary":"Stop gossip on this node. Every peer marks it Down and stops routing replica traffic to it, while it keeps serving whatever clients are still connected — the isolation move for a node that is poisoning cluster state, and the way to strand a node if used carelessly.","description":"Stop gossip on this node. Every peer marks it Down and stops routing replica traffic to it, while it keeps serving whatever clients are still connected — the isolation move for a node that is poisoning cluster state, and the way to strand a node if used carelessly.","kind":"exec","risk":"critical","side_effects":["The cluster treats this node as Down — reads and writes route to other replicas, and hints pile up for it.","The node keeps its own client connections, so it can serve stale data while isolated.","Reverse it with cassandra.nodetool_enablegossip; the node then needs a repair for what it missed."],"args":[],"examples":[{"title":"Isolate this node from the ring","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablegossip"]}},{"id":"cassandra.nodetool_disablehandoff","title":"nodetool disablehandoff","summary":"Stop this node storing hints for unreachable peers. Different from cassandra.nodetool_pausehandoff, which keeps storing them and only stops delivery. Use when hint disk use is the problem, not delivery load.","description":"Stop this node storing hints for unreachable peers. Different from cassandra.nodetool_pausehandoff, which keeps storing them and only stops delivery. Use when hint disk use is the problem, not delivery load.","kind":"exec","risk":"medium","side_effects":["Writes destined for a down peer are no longer saved, so recovering that peer needs a repair.","Existing hints stay on disk and still replay.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[],"examples":[{"title":"Stop storing hints","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablehandoff"]}},{"id":"cassandra.nodetool_disablehintsfordc","title":"nodetool disablehintsfordc <datacenter>","summary":"Stop this node storing hints for one datacenter — the move when a remote datacenter is down for maintenance, or is being retired, and its hints would otherwise pile up on every local node.","description":"Stop this node storing hints for one datacenter — the move when a remote datacenter is down for maintenance, or is being retired, and its hints would otherwise pile up on every local node.","kind":"exec","risk":"medium","side_effects":["Writes destined for that datacenter's replicas stop being saved, so bringing it back needs a repair.","Hints for other datacenters are unaffected.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"datacenter","type":"string","required":true,"description":"Datacenter name as the snitch reports it.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Stop hints for a retiring datacenter","args":{"datacenter":"gcp-us-east1"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablehintsfordc","--","{{ args.datacenter }}"]}},{"id":"cassandra.nodetool_drain","title":"nodetool drain","summary":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","description":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","kind":"exec","risk":"critical","side_effects":["Node stops accepting writes immediately.","All memtables flushed.","Native + Thrift transports closed.","Only restart restores the node."],"args":[],"examples":[{"title":"Drain before restart","args":{}}],"search_terms":["safe shutdown","flush before restart"],"command":{"binary":"nodetool","argv":["drain"]}},{"id":"cassandra.nodetool_enableautocompaction","title":"nodetool enableautocompaction <keyspace> [table]","summary":"Resume automatic compaction for a keyspace or one table on this node after a cassandra.nodetool_disableautocompaction. Confirm with cassandra.nodetool_statusautocompaction.","description":"Resume automatic compaction for a keyspace or one table on this node after a cassandra.nodetool_disableautocompaction. Confirm with cassandra.nodetool_statusautocompaction.","kind":"exec","risk":"medium","side_effects":["Compaction resumes immediately and works off whatever backlog accumulated, which is CPU and disk heavy on a large one.","The backlog respects the cap set by cassandra.nodetool_setcompactionthroughput."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to resume.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to resume; empty resumes every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Resume compaction on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enableautocompaction","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_enablebackup","title":"nodetool enablebackup","summary":"Start incremental backup on this node — every new SSTable is hard-linked into the table's backups directory for an external backup job to collect. Confirm with cassandra.nodetool_service_status.","description":"Start incremental backup on this node — every new SSTable is hard-linked into the table's backups directory for an external backup job to collect. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Each new SSTable gains a hard link that only an external job removes, so disk use grows until something clears them.","Covers SSTables written from now on, not existing data; that needs cassandra.nodetool_snapshot."],"args":[],"examples":[{"title":"Start incremental backup","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablebackup"]}},{"id":"cassandra.nodetool_enablebinary","title":"nodetool enablebinary","summary":"Start the native transport on this node so CQL clients can connect again — the recovery from cassandra.nodetool_disablebinary. Confirm with cassandra.nodetool_service_status.","description":"Start the native transport on this node so CQL clients can connect again — the recovery from cassandra.nodetool_disablebinary. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"critical","side_effects":["Clients start connecting immediately, so a node that is not ready to serve reads takes traffic at once.","Check the node is Up/Normal with cassandra.nodetool_status first."],"args":[],"examples":[{"title":"Return this node to client rotation","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablebinary"]}},{"id":"cassandra.nodetool_enablegossip","title":"nodetool enablegossip","summary":"Start gossip on this node so the cluster sees it as Up again — the recovery from cassandra.nodetool_disablegossip. Confirm with cassandra.nodetool_service_status and cassandra.nodetool_status.","description":"Start gossip on this node so the cluster sees it as Up again — the recovery from cassandra.nodetool_disablegossip. Confirm with cassandra.nodetool_service_status and cassandra.nodetool_status.","kind":"exec","risk":"critical","side_effects":["Peers mark the node Up and resume routing replica traffic to it at once.","Writes it missed arrive as hints only inside the hint window; anything older needs a repair."],"args":[],"examples":[{"title":"Rejoin the ring","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablegossip"]}},{"id":"cassandra.nodetool_enablehandoff","title":"nodetool enablehandoff","summary":"Resume storing hints for unreachable peers after a cassandra.nodetool_disablehandoff. Confirm with cassandra.nodetool_service_status.","description":"Resume storing hints for unreachable peers after a cassandra.nodetool_disablehandoff. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Writes for a down peer are saved again, using disk for as long as the window set by cassandra.nodetool_setmaxhintwindow.","Nothing recovers the hints missed while storing was off; that gap needs a repair."],"args":[],"examples":[{"title":"Store hints again","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablehandoff"]}},{"id":"cassandra.nodetool_enablehintsfordc","title":"nodetool enablehintsfordc <datacenter>","summary":"Resume storing hints for one datacenter after a cassandra.nodetool_disablehintsfordc — the step that goes with bringing a remote datacenter back into service.","description":"Resume storing hints for one datacenter after a cassandra.nodetool_disablehintsfordc — the step that goes with bringing a remote datacenter back into service.","kind":"exec","risk":"medium","side_effects":["Writes for that datacenter's replicas are saved again while they are unreachable.","Nothing recovers the hints missed while it was off; that gap needs a repair."],"args":[{"name":"datacenter","type":"string","required":true,"description":"Datacenter name as the snitch reports it.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Store hints for a datacenter again","args":{"datacenter":"va1"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablehintsfordc","--","{{ args.datacenter }}"]}},{"id":"cassandra.nodetool_failuredetector","title":"nodetool failuredetector","summary":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","description":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Phi scores","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["failuredetector"]}},{"id":"cassandra.nodetool_flush","title":"nodetool flush [ks] [table]","summary":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","description":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","kind":"exec","risk":"high","side_effects":["Memtables for the targeted scope are flushed to disk.","Brief IO spike.","Commit log may be marked clean for the affected segments."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table (requires keyspace).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Flush one keyspace","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool flush \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool flush \"$2\"; else nodetool flush; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_garbagecollect","title":"nodetool garbagecollect <keyspace> [table]","summary":"Rewrite a table's SSTables to drop data already deleted or expired, without waiting for compaction to reach it — the way to reclaim space from a tombstone-heavy table on one node. Slower and heavier than letting compaction do the work.","description":"Rewrite a table's SSTables to drop data already deleted or expired, without waiting for compaction to reach it — the way to reclaim space from a tombstone-heavy table on one node. Slower and heavier than letting compaction do the work.","kind":"exec","risk":"high","side_effects":["Rewrites every SSTable of the named tables on this node — sustained disk read, write, and CPU for the duration.","Needs free disk space for the rewritten files while it runs.","Data past gc_grace_seconds is purged; nothing recoverable is lost."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to collect.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to collect; empty collects every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"granularity","type":"string","required":false,"default":"ROW","description":"ROW drops deleted partitions and rows; CELL also drops overwritten and deleted cells, at more cost.","validation":{"enum":["ROW","CELL"]}}],"examples":[{"title":"Reclaim space on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["garbagecollect","-g","{{ args.granularity }}","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_gcstats","title":"nodetool gcstats","summary":"Show garbage-collection statistics since the last call — pause counts, max and total elapsed time, and memory reclaimed. Long pauses here explain client timeouts that the latency histograms alone do not.","description":"Show garbage-collection statistics since the last call — pause counts, max and total elapsed time, and memory reclaimed. Long pauses here explain client timeouts that the latency histograms alone do not.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only.","Counters reset on read, so each call reports the interval since the previous one."],"args":[],"examples":[{"title":"GC since the last read","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gcstats"]}},{"id":"cassandra.nodetool_getbatchlogreplaythrottle","title":"nodetool getbatchlogreplaythrottle","summary":"Show the current batchlog replay throttle in KiB/s.","description":"Show the current batchlog replay throttle in KiB/s.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current batchlog replay throttle","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getbatchlogreplaythrottle"]}},{"id":"cassandra.nodetool_getcompactionthreshold","title":"nodetool getcompactionthreshold <keyspace> <table>","summary":"Show the min and max size-tiered compaction thresholds for one table.","description":"Show the min and max size-tiered compaction thresholds for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Thresholds for one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthreshold","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_getcompactionthroughput","title":"nodetool getcompactionthroughput","summary":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","description":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Compaction throughput","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthroughput"]}},{"id":"cassandra.nodetool_getconcurrency","title":"nodetool getconcurrency","summary":"List every request-processing stage on this node with its core and maximum pool size — the thread limits cassandra.nodetool_setconcurrency changes.","description":"List every request-processing stage on this node with its core and maximum pool size — the thread limits cassandra.nodetool_setconcurrency changes.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Stage thread limits","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrency"]}},{"id":"cassandra.nodetool_getconcurrentcompactors","title":"nodetool getconcurrentcompactors","summary":"Show the current concurrent_compactors setting.","description":"Show the current concurrent_compactors setting.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent compactors","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentcompactors"]}},{"id":"cassandra.nodetool_getconcurrentviewbuilders","title":"nodetool getconcurrentviewbuilders","summary":"Show how many materialized-view builds this node runs at once.","description":"Show how many materialized-view builds this node runs at once.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent view builders","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentviewbuilders"]}},{"id":"cassandra.nodetool_getendpoints","title":"nodetool getendpoints <ks> <table> <key>","summary":"Show which replicas own a specific partition key. Use to confirm read/write routing.","description":"Show which replicas own a specific partition key. Use to confirm read/write routing.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key (as a literal).","validation":{"pattern":"^[a-zA-Z0-9_:.][a-zA-Z0-9_\\-:.]{0,255}$"}}],"examples":[{"title":"Owning replicas","args":{"key":"user-1234","keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getendpoints","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getinterdcstreamthroughput","title":"nodetool getinterdcstreamthroughput","summary":"Show this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters. Reports \"unlimited\" when throttling is off.","description":"Show this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters. Reports \"unlimited\" when throttling is off.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to read, and in which unit. stream_megabits reports Mb/s, stream_mib the same cap in MiB/s, and entire_sstable_mib the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Cross-datacenter stream throughput in Mb/s","args":{}},{"title":"Cross-datacenter stream throughput in MiB/s","args":{"cap":"stream_mib"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"-d\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool getinterdcstreamthroughput \"$flag\"\n"]}},{"id":"cassandra.nodetool_getlogginglevels","title":"nodetool getlogginglevels","summary":"Show the current per-logger levels.","description":"Show the current per-logger levels.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Logger levels","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getlogginglevels"]}},{"id":"cassandra.nodetool_getmaxhintwindow","title":"nodetool getmaxhintwindow","summary":"Show how long this node keeps writing hints for an unreachable peer, in milliseconds.","description":"Show how long this node keeps writing hints for an unreachable peer, in milliseconds.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current hint window","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getmaxhintwindow"]}},{"id":"cassandra.nodetool_getseeds","title":"nodetool getseeds","summary":"List the seed nodes this node is currently using, excluding its own address — the running value, which drifts from cassandra.yaml after a cassandra.nodetool_reloadseeds or a seed-provider change.","description":"List the seed nodes this node is currently using, excluding its own address — the running value, which drifts from cassandra.yaml after a cassandra.nodetool_reloadseeds or a seed-provider change.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Seeds in use","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getseeds"]}},{"id":"cassandra.nodetool_getsnapshotthrottle","title":"nodetool getsnapshotthrottle","summary":"Show how many hard links per second snapshot and clearsnapshot may create. An unthrottled node reports the maximum long value rather than a word.","description":"Show how many hard links per second snapshot and clearsnapshot may create. An unthrottled node reports the maximum long value rather than a word.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current snapshot throttle","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getsnapshotthrottle"]}},{"id":"cassandra.nodetool_getsstables","title":"nodetool getsstables <keyspace> <table> <key>","summary":"List the SSTable files that hold one partition key — how many files a read of that key must touch. Empty output means the key's data is still in the memtable or absent.","description":"List the SSTable files that hold one partition key — how many files a read of that key must touch. Empty output means the key's data is still in the memtable or absent.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table holding the key.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key, in the string form nodetool accepts.","validation":{"pattern":"^[A-Za-z0-9._:+@-]{1,128}$","max_length":128}}],"examples":[{"title":"Files holding one key","args":{"key":"a41f2c7e","keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getsstables","--","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getstreamthroughput","title":"nodetool getstreamthroughput","summary":"Show this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Reports \"unlimited\" when throttling is off.","description":"Show this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Reports \"unlimited\" when throttling is off.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to read, and in which unit. stream_megabits reports Mb/s, stream_mib the same cap in MiB/s, and entire_sstable_mib the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Stream throughput in Mb/s","args":{}},{"title":"Stream throughput in MiB/s","args":{"cap":"stream_mib"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"-d\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool getstreamthroughput \"$flag\"\n"]}},{"id":"cassandra.nodetool_gettimeout","title":"nodetool gettimeout <type>","summary":"Show one of this node's request or internode timeouts, in milliseconds.","description":"Show one of this node's request or internode timeouts, in milliseconds.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"timeout_type","type":"string","required":true,"description":"Timeout to read.","validation":{"enum":["read","range","write","counterwrite","cascontention","truncate","internodeconnect","internodeuser","internodestreaminguser","misc"]}}],"examples":[{"title":"Current read timeout","args":{"timeout_type":"read"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gettimeout","{{ args.timeout_type }}"]}},{"id":"cassandra.nodetool_gettraceprobability","title":"nodetool gettraceprobability","summary":"Show the fraction of requests this node traces (0 = tracing off).","description":"Show the fraction of requests this node traces (0 = tracing off).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current trace probability","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gettraceprobability"]}},{"id":"cassandra.nodetool_gossipinfo","title":"nodetool gossipinfo","summary":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","description":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Gossip view","args":{}}],"search_terms":["node stuck joining"],"command":{"binary":"nodetool","argv":["gossipinfo"]}},{"id":"cassandra.nodetool_info","title":"nodetool info","summary":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","description":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"This node","args":{}}],"search_terms":["node uptime","heap usage"],"command":{"binary":"nodetool","argv":["info"]}},{"id":"cassandra.nodetool_invalidatecountercache","title":"nodetool invalidatecountercache","summary":"Drop the counter cache.","description":"Drop the counter cache.","kind":"exec","risk":"medium","side_effects":["Counter cache cleared.","Counter reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop counter cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecountercache"]}},{"id":"cassandra.nodetool_invalidatecredentialscache","title":"nodetool invalidatecredentialscache","summary":"Drop this node's cached credentials so a changed or revoked password takes effect now instead of when the cache expires. Needs PasswordAuthenticator.","description":"Drop this node's cached credentials so a changed or revoked password takes effect now instead of when the cache expires. Needs PasswordAuthenticator.","kind":"exec","risk":"medium","side_effects":["The next authentication for each role reads from the auth keyspace, so sign-ins are briefly slower.","Sessions already authenticated are not disconnected."],"args":[],"examples":[{"title":"Apply a password change now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecredentialscache"]}},{"id":"cassandra.nodetool_invalidatekeycache","title":"nodetool invalidatekeycache","summary":"Drop the key cache. Reads pay cold-cache cost until it warms.","description":"Drop the key cache. Reads pay cold-cache cost until it warms.","kind":"exec","risk":"medium","side_effects":["Key cache cleared.","Next reads must do bloom-filter + summary + index lookups."],"args":[],"examples":[{"title":"Drop key cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatekeycache"]}},{"id":"cassandra.nodetool_invalidatepermissionscache","title":"nodetool invalidatepermissionscache","summary":"Drop this node's cached permissions so a GRANT or REVOKE takes effect now instead of when the cache expires. Needs CassandraAuthorizer.","description":"Drop this node's cached permissions so a GRANT or REVOKE takes effect now instead of when the cache expires. Needs CassandraAuthorizer.","kind":"exec","risk":"medium","side_effects":["The next request per role and resource re-reads permissions, so queries are briefly slower.","Sessions already authorized keep running; only the next permission check is re-evaluated."],"args":[],"examples":[{"title":"Apply a REVOKE now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatepermissionscache"]}},{"id":"cassandra.nodetool_invalidaterolescache","title":"nodetool invalidaterolescache","summary":"Drop this node's cached roles so a role or membership change takes effect now instead of when the cache expires — the companion to cassandra.nodetool_invalidatepermissionscache after editing roles.","description":"Drop this node's cached roles so a role or membership change takes effect now instead of when the cache expires — the companion to cassandra.nodetool_invalidatepermissionscache after editing roles.","kind":"exec","risk":"medium","side_effects":["The next request per role re-reads the roles table, so queries are briefly slower.","Sessions already authenticated keep running under the reloaded role."],"args":[],"examples":[{"title":"Apply a role change now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterolescache"]}},{"id":"cassandra.nodetool_invalidaterowcache","title":"nodetool invalidaterowcache","summary":"Drop the row cache.","description":"Drop the row cache.","kind":"exec","risk":"medium","side_effects":["Row cache cleared.","Next reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop row cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterowcache"]}},{"id":"cassandra.nodetool_listpendinghints","title":"nodetool listpendinghints","summary":"List the hints this node is holding for peers that were unreachable — how much replay is waiting, and for whom. Reports plainly when there are none.","description":"List the hints this node is holding for peers that were unreachable — how much replay is waiting, and for whom. Reports plainly when there are none.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Hints waiting to replay","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listpendinghints"]}},{"id":"cassandra.nodetool_listsnapshots","title":"nodetool listsnapshots","summary":"List all snapshots on this node with size + creation timestamp.","description":"List all snapshots on this node with size + creation timestamp.","kind":"exec","risk":"low","side_effects":["Reads disk metadata.","Read-only."],"args":[],"examples":[{"title":"All snapshots","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listsnapshots"]}},{"id":"cassandra.nodetool_netstats","title":"nodetool netstats","summary":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","description":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Net stats","args":{}}],"search_terms":["streaming progress","streaming stuck","bootstrap progress"],"command":{"binary":"nodetool","argv":["netstats"]}},{"id":"cassandra.nodetool_pausehandoff","title":"nodetool pausehandoff","summary":"Pause hint delivery from this node. Hints keep accumulating; only the replay to peers stops — the move when a peer that just came back is being flooded. Resume with cassandra.nodetool_resumehandoff.","description":"Pause hint delivery from this node. Hints keep accumulating; only the replay to peers stops — the move when a peer that just came back is being flooded. Resume with cassandra.nodetool_resumehandoff.","kind":"exec","risk":"medium","side_effects":["Stored hints stop replaying; they stay on disk and grow.","Peers stay inconsistent until delivery resumes or a repair runs.","Runtime-only — a restart resumes delivery."],"args":[],"examples":[{"title":"Pause hint delivery","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["pausehandoff"]}},{"id":"cassandra.nodetool_proxyhistograms","title":"nodetool proxyhistograms","summary":"Show coordinator-side read/write latency histograms — what clients actually see.","description":"Show coordinator-side read/write latency histograms — what clients actually see.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Coordinator latencies","args":{}}],"search_terms":["p99 latency","latency percentiles","reads are slow","writes are slow"],"command":{"binary":"nodetool","argv":["proxyhistograms"]}},{"id":"cassandra.nodetool_rebuild","title":"nodetool rebuild [source_dc]","summary":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","description":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","kind":"exec","risk":"high","side_effects":["Heavy streaming workload.","Existing data on this node is NOT removed first.","Best run on a node that has empty data dirs."],"args":[{"name":"source_dc","type":"string","required":false,"default":"","description":"Source DC name (empty = any).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rebuild from us-east","args":{"source_dc":"us-east"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool rebuild \"$1\"; else nodetool rebuild; fi","emisar","{{ args.source_dc }}"]}},{"id":"cassandra.nodetool_rebuild_index","title":"nodetool rebuild_index <keyspace> <table> <index>","summary":"Rebuild one secondary index on this node from its base table — the fix when an index returns stale or missing rows after a restore, a scrub, or index corruption.","description":"Rebuild one secondary index on this node from its base table — the fix when an index returns stale or missing rows after a restore, a scrub, or index corruption.","kind":"exec","risk":"high","side_effects":["Reads the whole base table on this node and rewrites the index — sustained disk and CPU for the duration.","Queries using the index return incomplete results until the rebuild finishes."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Base table of the index.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"index","type":"string","required":true,"description":"Index name as the schema declares it.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Rebuild one index","args":{"index":"matches_player_idx","keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["rebuild_index","--","{{ args.keyspace }}","{{ args.table }}","{{ args.index }}"]}},{"id":"cassandra.nodetool_refresh","title":"nodetool refresh <keyspace> <table>","summary":"Load SSTable files that were placed into a table's data directory into the running node, with no restart — the last step of a file-level restore. Cassandra 5.0 prints a deprecation notice pointing at `nodetool import`, and still performs the load.","description":"Load SSTable files that were placed into a table's data directory into the running node, with no restart — the last step of a file-level restore. Cassandra 5.0 prints a deprecation notice pointing at `nodetool import`, and still performs the load.","kind":"exec","risk":"medium","side_effects":["The node starts serving whatever rows those files contain; a wrong file set changes query results.","Loading a large file set triggers compaction on the table."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table whose directory holds the new files.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Pick up restored SSTables","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["refresh","--","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_refreshsizeestimates","title":"nodetool refreshsizeestimates","summary":"Recompute the system.size_estimates table this node publishes. Run it when cassandra.cqlsh_system_size_estimates looks stale — Spark and analytics connectors split work from those numbers.","description":"Recompute the system.size_estimates table this node publishes. Run it when cassandra.cqlsh_system_size_estimates looks stale — Spark and analytics connectors split work from those numbers.","kind":"exec","risk":"medium","side_effects":["Rewrites this node's size_estimates rows; it reads SSTable metadata, not data.","Cheap on a small node, noticeable on one with many tables."],"args":[],"examples":[{"title":"Recompute size estimates","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["refreshsizeestimates"]}},{"id":"cassandra.nodetool_reloadlocalschema","title":"nodetool reloadlocalschema","summary":"Reload this node's schema from its own system tables — the first, cheap remedy when cassandra.nodetool_describecluster reports this node on a different schema version from the rest.","description":"Reload this node's schema from its own system tables — the first, cheap remedy when cassandra.nodetool_describecluster reports this node on a different schema version from the rest.","kind":"exec","risk":"medium","side_effects":["Rebuilds the in-memory schema from local system tables; it pulls nothing from peers and drops nothing.","Brief pause on schema-dependent work while it reloads."],"args":[],"examples":[{"title":"Reload the local schema","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadlocalschema"]}},{"id":"cassandra.nodetool_reloadseeds","title":"nodetool reloadseeds","summary":"Re-read the seed list from the seed provider without restarting — the step after editing seeds in cassandra.yaml, typically while replacing seed nodes. Read the result back with cassandra.nodetool_getseeds.","description":"Re-read the seed list from the seed provider without restarting — the step after editing seeds in cassandra.yaml, typically while replacing seed nodes. Read the result back with cassandra.nodetool_getseeds.","kind":"exec","risk":"medium","side_effects":["Replaces the in-memory seed list; gossip with current peers is unaffected.","Prints the new list, or says the provider returned no remote addresses."],"args":[],"examples":[{"title":"Re-read the seed list","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadseeds"]}},{"id":"cassandra.nodetool_reloadssl","title":"nodetool reloadssl","summary":"Reload the keystore and truststore from disk so a renewed certificate takes effect without a restart — the step that finishes a certificate rotation on a live node.","description":"Reload the keystore and truststore from disk so a renewed certificate takes effect without a restart — the step that finishes a certificate rotation on a live node.","kind":"exec","risk":"medium","side_effects":["New connections use the reloaded material; connections already established keep their current session.","A keystore that is unreadable or has the wrong password fails here, before it can break new connections."],"args":[],"examples":[{"title":"Pick up a renewed certificate","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadssl"]}},{"id":"cassandra.nodetool_relocatesstables","title":"nodetool relocatesstables <keyspace> <table>","summary":"Move a table's SSTables onto the disk that owns their token range — the fix after adding or replacing a data directory on a node that spreads data across several disks. A no-op on a node with one data directory.","description":"Move a table's SSTables onto the disk that owns their token range — the fix after adding or replacing a data directory on a node that spreads data across several disks. A no-op on a node with one data directory.","kind":"exec","risk":"high","side_effects":["Rewrites SSTables onto their correct disk — sustained disk read and write for the duration.","Needs free space on the target disk while files are moved."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to relocate.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to relocate.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Rebalance one table across disks","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["relocatesstables","--","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_removenode","title":"nodetool removenode <host-id>","summary":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","description":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","kind":"exec","risk":"critical","side_effects":["Other replicas stream the dead node's data to their successors.","Heavy network + disk during stream.","Token range reassigned permanently."],"args":[{"name":"host_id","type":"string","required":true,"description":"Host ID UUID (from nodetool status).","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Remove a down node","args":{"host_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["remove dead node"],"command":{"binary":"nodetool","argv":["removenode","{{ args.host_id }}"]}},{"id":"cassandra.nodetool_repair","title":"Cassandra repair","summary":"Wrap `nodetool repair`.","description":"Wrap `nodetool repair`. The most dangerous \"normal\" operation — repair reconciles data between replicas, can take hours, produces significant cluster-wide load, may interact poorly with TTL/tombstone-heavy tables, and can worsen latency on every replica it touches. Always inspect ring status, compactions, disk, and logs first. Prefer mode=preview — a dry run that estimates the repair without performing it (requires Cassandra 4.0+) — before a real repair. Refuse to proceed if the ring has DN/UJ/UL/UM nodes.","kind":"exec","risk":"high","side_effects":["Repair coordinates with replicas across the cluster.","Generates significant network, CPU, and disk I/O.","Schedules anti-compaction and validation tasks.","Can run for minutes to hours depending on dataset size.","May worsen latency on the local node and on replica nodes for the duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to repair.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional single table to repair (empty = whole keyspace).","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"mode","type":"string","required":false,"default":"preview","description":"Repair mode.","validation":{"enum":["preview","full","incremental"]}},{"name":"primary_range","type":"boolean","required":false,"default":true,"description":"Restrict to the primary token range (recommended)."},{"name":"parallelism","type":"string","required":false,"default":"sequential","description":"Parallelism mode.","validation":{"enum":["sequential","parallel","dc_parallel"]}}],"examples":[{"title":"Dry-run repair preview on one keyspace","args":{"keyspace":"valorant_ks","mode":"preview"}}],"search_terms":["anti-entropy","inconsistent replicas","data consistency"],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\ncase \"$MODE\" in\n  preview) flags=\"--preview\" ;;\n  full) flags=\"-full\" ;;\n  # Incremental is nodetool's own default on 4.x and 5.x and has no flag\n  # of its own (-inc went away after 3.x). Named anyway: falling through\n  # meant the operator asked for incremental and silently got whatever\n  # this node's version defaults to, and the next enum value added here\n  # would have inherited the same silence.\n  incremental) flags=\"\" ;;\n  *) printf 'unsupported repair mode: %s\\n' \"$MODE\" >&2; exit 2 ;;\nesac\n[ \"$PR\" = \"true\" ] && flags=\"$flags -pr\"\ncase \"$PAR\" in\n  sequential) flags=\"$flags -seq\" ;;\n  dc_parallel) flags=\"$flags -dcpar\" ;;\nesac\nset -- \"$KS\"\n[ -n \"$TBL\" ] && set -- \"$@\" \"$TBL\"\nexec nodetool repair $flags \"$@\"\n"]}},{"id":"cassandra.nodetool_repair_admin_list","title":"nodetool repair_admin list","summary":"List the incremental repair sessions this node knows about. A session stuck in a non-finished state is what keeps SSTables pending repair and blocks later repairs; \"no sessions\" is the healthy answer.","description":"List the incremental repair sessions this node knows about. A session stuck in a non-finished state is what keeps SSTables pending repair and blocks later repairs; \"no sessions\" is the healthy answer.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"include_completed","type":"boolean","required":false,"default":false,"description":"Include finished sessions as well as the ones still in flight."}],"examples":[{"title":"Sessions still in flight","args":{}},{"title":"Every recorded session","args":{"include_completed":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ \"$ALL\" = \"true\" ] && exec nodetool repair_admin list --all\nexec nodetool repair_admin list\n"]}},{"id":"cassandra.nodetool_replaybatchlog","title":"nodetool replaybatchlog","summary":"Replay this node's batchlog now and wait for it to finish, instead of waiting for the periodic sweep — the step that clears batches left behind after a node came back from an outage.","description":"Replay this node's batchlog now and wait for it to finish, instead of waiting for the periodic sweep — the step that clears batches left behind after a node came back from an outage.","kind":"exec","risk":"medium","side_effects":["Replays batched writes to their replicas, adding write load until the backlog clears.","Blocks until the replay finishes.","The rate honours the cap set by cassandra.nodetool_setbatchlogreplaythrottle."],"args":[],"examples":[{"title":"Clear the batchlog now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["replaybatchlog"]}},{"id":"cassandra.nodetool_resumehandoff","title":"nodetool resumehandoff","summary":"Resume hint delivery from this node after a cassandra.nodetool_pausehandoff. Confirm with cassandra.nodetool_service_status.","description":"Resume hint delivery from this node after a cassandra.nodetool_pausehandoff. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Stored hints start replaying to their peers immediately.","A large backlog puts load on this node and on the peers receiving it; cap it with cassandra.nodetool_sethintedhandoffthrottlekb."],"args":[],"examples":[{"title":"Resume hint delivery","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["resumehandoff"]}},{"id":"cassandra.nodetool_ring","title":"nodetool ring [keyspace]","summary":"Show the token ring with owner host per token.","description":"Show the token ring with owner host per token.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (default — all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Ring","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool ring \"$1\"; else nodetool ring; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_scrub","title":"nodetool scrub <keyspace> [table]","summary":"Rebuild a table's SSTables on this node, validating each row as it goes — the repair for corrupt files reported in the log. Snapshots first by default, so the pre-scrub files remain until you clear that snapshot.","description":"Rebuild a table's SSTables on this node, validating each row as it goes — the repair for corrupt files reported in the log. Snapshots first by default, so the pre-scrub files remain until you clear that snapshot.","kind":"exec","risk":"high","side_effects":["Rewrites every SSTable of the named tables — sustained disk and CPU for the duration.","Takes a snapshot first, which occupies disk until cassandra.nodetool_clearsnapshot removes it.","With skip_corrupted, unreadable rows are dropped instead of failing the scrub; that data is gone from this node and needs a repair."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to scrub.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to scrub; empty scrubs every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"skip_corrupted","type":"boolean","required":false,"default":false,"description":"Drop rows that cannot be read instead of stopping at them."}],"examples":[{"title":"Scrub one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\n[ \"$SKIP_CORRUPTED\" = \"true\" ] && flags=\"-s\"\nset -- \"$KEYSPACE\"\n[ -n \"$TABLE\" ] && set -- \"$@\" \"$TABLE\"\nexec nodetool scrub $flags -- \"$@\"\n"]}},{"id":"cassandra.nodetool_service_status","title":"nodetool statusbinary / statusgossip / statusbackup / statushandoff","summary":"Check what this node currently has switched on — native transport (client traffic), gossip, incremental backup, and hinted handoff — in one call. The read to take before and after any of the enable/disable actions.","description":"Check what this node currently has switched on — native transport (client traffic), gossip, incremental backup, and hinted handoff — in one call. The read to take before and after any of the enable/disable actions.","kind":"exec","risk":"low","side_effects":["Four JMX calls.","Read-only."],"args":[],"examples":[{"title":"What is switched on","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","for check in statusbinary statusgossip statusbackup statushandoff; do\n  printf '%s: ' \"$check\"\n  nodetool \"$check\" || exit $?\ndone\n"]}},{"id":"cassandra.nodetool_setbatchlogreplaythrottle","title":"nodetool setbatchlogreplaythrottle <KiB/s>","summary":"Set the batchlog replay throttle in KiB/s. Lower it when replaying batches after an outage is adding load to an already busy node; 0 disables throttling. Read the current value with cassandra.nodetool_getbatchlogreplaythrottle.","description":"Set the batchlog replay throttle in KiB/s. Lower it when replaying batches after an outage is adding load to an already busy node; 0 disables throttling. Read the current value with cassandra.nodetool_getbatchlogreplaythrottle.","kind":"exec","risk":"medium","side_effects":["Applies to replay work that starts after the change.","Cassandra reduces the rate proportionally to the number of nodes in the cluster.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"kb_per_sec","type":"integer","required":true,"description":"Throttle in KiB/s; 0 disables throttling.","validation":{"min":0,"max":1048576}}],"examples":[{"title":"Halve the default replay rate","args":{"kb_per_sec":512}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setbatchlogreplaythrottle","{{ args.kb_per_sec }}"]}},{"id":"cassandra.nodetool_setcachecapacity","title":"nodetool setcachecapacity <key MB> <row MB> <counter MB>","summary":"Set the key, row, and counter cache capacities in MB. All three are set in one call, so pass the current value for any cache you are not changing; 0 disables a cache. cassandra.nodetool_info reports the capacities in use.","description":"Set the key, row, and counter cache capacities in MB. All three are set in one call, so pass the current value for any cache you are not changing; 0 disables a cache. cassandra.nodetool_info reports the capacities in use.","kind":"exec","risk":"medium","side_effects":["Shrinking a cache evicts entries immediately, so reads run cold until it refills.","The key and counter caches live on the JVM heap — oversizing them adds GC pressure on the node.","Runtime-only — a restart returns the node to its cassandra.yaml values."],"args":[{"name":"key_cache_mb","type":"integer","required":true,"description":"Key cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}},{"name":"row_cache_mb","type":"integer","required":true,"description":"Row cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}},{"name":"counter_cache_mb","type":"integer","required":true,"description":"Counter cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}}],"examples":[{"title":"512 MB key cache, row cache off, 128 MB counter cache","args":{"counter_cache_mb":128,"key_cache_mb":512,"row_cache_mb":0}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcachecapacity","{{ args.key_cache_mb }}","{{ args.row_cache_mb }}","{{ args.counter_cache_mb }}"]}},{"id":"cassandra.nodetool_setcompactionthreshold","title":"nodetool setcompactionthreshold <keyspace> <table> <min> <max>","summary":"Set the min and max SSTable count that triggers size-tiered compaction for one table. Raising the minimum makes the table compact less often and keeps more SSTables; lowering it compacts sooner. Read the current pair with cassandra.nodetool_getcompactionthreshold.","description":"Set the min and max SSTable count that triggers size-tiered compaction for one table. Raising the minimum makes the table compact less often and keeps more SSTables; lowering it compacts sooner. Read the current pair with cassandra.nodetool_getcompactionthreshold.","kind":"exec","risk":"medium","side_effects":["Applies to this table on this node only, and takes effect on the next compaction decision.","A higher minimum leaves more SSTables per read until the next compaction.","Runtime-only — a restart returns the table to its schema value."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to change.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"min_threshold","type":"integer","required":true,"description":"SSTables of one size tier needed before compaction starts (nodetool requires at least 2).","validation":{"min":2,"max":1000}},{"name":"max_threshold","type":"integer","required":true,"description":"Most SSTables compacted at once; must not be below min_threshold.","validation":{"min":2,"max":1000}}],"examples":[{"title":"Standard size-tiered thresholds","args":{"keyspace":"valorant_ks","max_threshold":32,"min_threshold":4,"table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthreshold","{{ args.keyspace }}","{{ args.table }}","{{ args.min_threshold }}","{{ args.max_threshold }}"]}},{"id":"cassandra.nodetool_setcompactionthroughput","title":"nodetool setcompactionthroughput <MB/s>","summary":"Set max compaction throughput. 0 = unlimited (use carefully).","description":"Set max compaction throughput. 0 = unlimited (use carefully).","kind":"exec","risk":"medium","side_effects":["In-flight + future compactions throttled to the new cap.","Lower values reduce IO pressure but grow SSTable count."],"args":[{"name":"mb_per_sec","type":"integer","required":true,"description":"MB/s; 0 = unlimited.","validation":{"min":0,"max":10000}}],"examples":[{"title":"Throttle to 16 MB/s","args":{"mb_per_sec":16}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthroughput","{{ args.mb_per_sec }}"]}},{"id":"cassandra.nodetool_setconcurrency","title":"nodetool setconcurrency <stage> <max>","summary":"Set the maximum number of threads one request-processing stage may use. Lower a stage to stop it crowding out the rest of the node, raise it when a stage is the bottleneck. List the stages and their current sizes with cassandra.nodetool_getconcurrency.","description":"Set the maximum number of threads one request-processing stage may use. Lower a stage to stop it crowding out the rest of the node, raise it when a stage is the bottleneck. List the stages and their current sizes with cassandra.nodetool_getconcurrency.","kind":"exec","risk":"medium","side_effects":["Applies immediately; work already queued on the stage runs under the new limit.","Starving a stage that serves live traffic (MUTATION, READ) shows up as client timeouts.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"stage","type":"string","required":true,"description":"Stage to resize, under the name nodetool accepts — MUTATION is the MutationStage that cassandra.nodetool_getconcurrency prints.","validation":{"enum":["READ","MUTATION","COUNTER_MUTATION","VIEW_MUTATION","GOSSIP","REQUEST_RESPONSE","ANTI_ENTROPY","MIGRATION","MISC","TRACING","INTERNAL_RESPONSE","IMMEDIATE","PAXOS_REPAIR"]}},{"name":"max_concurrency","type":"integer","required":true,"description":"Maximum threads for the stage.","validation":{"min":1,"max":1024}}],"examples":[{"title":"Hold write threads at 16","args":{"max_concurrency":16,"stage":"MUTATION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrency","{{ args.stage }}","{{ args.max_concurrency }}"]}},{"id":"cassandra.nodetool_setconcurrentcompactors","title":"nodetool setconcurrentcompactors <count>","summary":"Set how many compactions this node runs at once. Raise it to work off a compaction backlog, lower it to give CPU and disk back to reads and writes. Read the current value with cassandra.nodetool_getconcurrentcompactors.","description":"Set how many compactions this node runs at once. Raise it to work off a compaction backlog, lower it to give CPU and disk back to reads and writes. Read the current value with cassandra.nodetool_getconcurrentcompactors.","kind":"exec","risk":"medium","side_effects":["New compactions pick up the limit; compactions already running are not stopped.","Each compactor consumes CPU and disk IO, and shares the cap set by cassandra.nodetool_setcompactionthroughput.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"count","type":"integer","required":true,"description":"Number of concurrent compactors.","validation":{"min":1,"max":128}}],"examples":[{"title":"Allow four concurrent compactions","args":{"count":4}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrentcompactors","{{ args.count }}"]}},{"id":"cassandra.nodetool_setconcurrentviewbuilders","title":"nodetool setconcurrentviewbuilders <count>","summary":"Set how many materialized-view builds this node runs at once. Lower it when a view build is competing with live traffic, raise it to finish a build sooner. Read the current value with cassandra.nodetool_getconcurrentviewbuilders.","description":"Set how many materialized-view builds this node runs at once. Lower it when a view build is competing with live traffic, raise it to finish a build sooner. Read the current value with cassandra.nodetool_getconcurrentviewbuilders.","kind":"exec","risk":"medium","side_effects":["New view builds pick up the limit; builds already running are not stopped.","Each builder reads base-table data and writes view rows, adding CPU and disk IO.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"count","type":"integer","required":true,"description":"Number of concurrent view builders.","validation":{"min":1,"max":128}}],"examples":[{"title":"Hold view builds to one at a time","args":{"count":1}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrentviewbuilders","{{ args.count }}"]}},{"id":"cassandra.nodetool_sethintedhandoffthrottlekb","title":"nodetool sethintedhandoffthrottlekb <KiB/s>","summary":"Set the hinted-handoff delivery throttle in KiB/s, per delivery thread. Lower it when a peer coming back online is being flooded with replayed hints; raise it to clear a hint backlog faster.","description":"Set the hinted-handoff delivery throttle in KiB/s, per delivery thread. Lower it when a peer coming back online is being flooded with replayed hints; raise it to clear a hint backlog faster.","kind":"exec","risk":"medium","side_effects":["Applies to hint deliveries that start after the change.","Cassandra divides the rate across live peers, so the effective per-peer rate is lower in a large cluster.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"kb_per_sec","type":"integer","required":true,"description":"Throttle in KiB/s, per delivery thread.","validation":{"min":1,"max":1048576}}],"examples":[{"title":"Halve the default hint delivery rate","args":{"kb_per_sec":512}}],"search_terms":[],"command":{"binary":"nodetool","argv":["sethintedhandoffthrottlekb","{{ args.kb_per_sec }}"]}},{"id":"cassandra.nodetool_setinterdcstreamthroughput","title":"nodetool setinterdcstreamthroughput <value>","summary":"Set this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters during rebuild, bootstrap, and repair. Protects a shared or metered inter-datacenter link while local streaming keeps its own cap from cassandra.nodetool_setstreamthroughput. 0 disables throttling.","description":"Set this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters during rebuild, bootstrap, and repair. Protects a shared or metered inter-datacenter link while local streaming keeps its own cap from cassandra.nodetool_setstreamthroughput. 0 disables throttling.","kind":"exec","risk":"medium","side_effects":["Applies immediately, to streams already in flight as well as new ones.","A cap under the current rate slows a running cross-datacenter rebuild; 0 lets it saturate the link.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"value","type":"integer","required":true,"description":"Cap in the unit named by cap; 0 disables throttling.","validation":{"min":0,"max":100000}},{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to set, and in which unit. stream_megabits is nodetool's own default (Mb/s); stream_mib is the same cap in MiB/s; entire_sstable_mib is the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Hold cross-datacenter streaming to 800 Mb/s","args":{"value":800}},{"title":"Hold cross-datacenter streaming to 40 MiB/s","args":{"cap":"stream_mib","value":40}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool setinterdcstreamthroughput $flag -- \"$VALUE\"\n"]}},{"id":"cassandra.nodetool_setlogginglevel","title":"nodetool setlogginglevel <logger> <level>","summary":"Set one logger's level. Use empty logger to reset all to the configured defaults.","description":"Set one logger's level. Use empty logger to reset all to the configured defaults.","kind":"exec","risk":"medium","side_effects":["Logger level changes immediately.","DEBUG/TRACE levels can dramatically increase log volume."],"args":[{"name":"logger","type":"string","required":true,"description":"Logger name (e.g. org.apache.cassandra.db, or \"root\").","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"level","type":"string","required":true,"description":"Level.","validation":{"enum":["TRACE","DEBUG","INFO","WARN","ERROR","OFF"]}}],"examples":[{"title":"Set DB layer to DEBUG","args":{"level":"DEBUG","logger":"org.apache.cassandra.db"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setlogginglevel","{{ args.logger }}","{{ args.level }}"]}},{"id":"cassandra.nodetool_setmaxhintwindow","title":"nodetool setmaxhintwindow <ms>","summary":"Set how long this node keeps writing hints for an unreachable peer, in milliseconds. Raise it to carry a peer through a longer maintenance window without a repair afterwards; 0 stops hint storage entirely. Read the current window with cassandra.nodetool_getmaxhintwindow.","description":"Set how long this node keeps writing hints for an unreachable peer, in milliseconds. Raise it to carry a peer through a longer maintenance window without a repair afterwards; 0 stops hint storage entirely. Read the current window with cassandra.nodetool_getmaxhintwindow.","kind":"exec","risk":"medium","side_effects":["A longer window stores more hints on disk and lengthens replay when the peer returns.","Writes made while a peer is down past the window are only recoverable by repair.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"window_ms","type":"integer","required":true,"description":"Hint window in milliseconds; 0 stops storing hints.","validation":{"min":0,"max":604800000}}],"examples":[{"title":"Hold hints for six hours","args":{"window_ms":21600000}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setmaxhintwindow","{{ args.window_ms }}"]}},{"id":"cassandra.nodetool_setsnapshotthrottle","title":"nodetool setsnapshotthrottle <links/s>","summary":"Set how many hard links per second snapshot and clearsnapshot may create. Lower it when taking a snapshot of a large node stalls the filesystem; 0 disables throttling. Read the current value with cassandra.nodetool_getsnapshotthrottle.","description":"Set how many hard links per second snapshot and clearsnapshot may create. Lower it when taking a snapshot of a large node stalls the filesystem; 0 disables throttling. Read the current value with cassandra.nodetool_getsnapshotthrottle.","kind":"exec","risk":"medium","side_effects":["Applies to snapshot work that starts after the change.","A low rate makes cassandra.nodetool_snapshot and cassandra.nodetool_clearsnapshot take proportionally longer on a table with many SSTables.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"links_per_sec","type":"integer","required":true,"description":"Hard links per second; 0 disables throttling.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Cap snapshot link creation","args":{"links_per_sec":200}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setsnapshotthrottle","{{ args.links_per_sec }}"]}},{"id":"cassandra.nodetool_setstreamthroughput","title":"nodetool setstreamthroughput <value>","summary":"Set this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Covers every stream the node sends; cross-datacenter streams are additionally capped by cassandra.nodetool_setinterdcstreamthroughput. 0 disables throttling.","description":"Set this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Covers every stream the node sends; cross-datacenter streams are additionally capped by cassandra.nodetool_setinterdcstreamthroughput. 0 disables throttling.","kind":"exec","risk":"medium","side_effects":["Applies immediately, to streams already in flight as well as new ones.","A cap under the current rate slows a running rebuild or repair; 0 lets streaming saturate the link.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"value","type":"integer","required":true,"description":"Cap in the unit named by cap; 0 disables throttling.","validation":{"min":0,"max":100000}},{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to set, and in which unit. stream_megabits is nodetool's own default (Mb/s); stream_mib is the same cap in MiB/s; entire_sstable_mib is the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Throttle streaming to 200 Mb/s","args":{"value":200}},{"title":"Throttle streaming to 64 MiB/s","args":{"cap":"stream_mib","value":64}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool setstreamthroughput $flag -- \"$VALUE\"\n"]}},{"id":"cassandra.nodetool_settimeout","title":"nodetool settimeout <type> <ms>","summary":"Set one of this node's request or internode timeouts, in milliseconds. Raise a timeout to ride out a slow period instead of failing queries, or lower it to fail fast. Read the current value with cassandra.nodetool_gettimeout.","description":"Set one of this node's request or internode timeouts, in milliseconds. Raise a timeout to ride out a slow period instead of failing queries, or lower it to fail fast. Read the current value with cassandra.nodetool_gettimeout.","kind":"exec","risk":"medium","side_effects":["Applies to requests that start after the change; requests in flight keep the old timeout.","A raised timeout holds threads and memory longer under load, which can turn a slow node into an unresponsive one.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"timeout_type","type":"string","required":true,"description":"Timeout to change.","validation":{"enum":["read","range","write","counterwrite","cascontention","truncate","internodeconnect","internodeuser","internodestreaminguser","misc"]}},{"name":"timeout_ms","type":"integer","required":true,"description":"Timeout in milliseconds. nodetool also takes 0, which for a request timeout means every request of that type fails at once rather than \"no limit\", so this action starts at 1.","validation":{"min":1,"max":3600000}}],"examples":[{"title":"Give reads two more seconds","args":{"timeout_ms":7000,"timeout_type":"read"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["settimeout","{{ args.timeout_type }}","{{ args.timeout_ms }}"]}},{"id":"cassandra.nodetool_settraceprobability","title":"nodetool settraceprobability <probability>","summary":"Set the fraction of requests this node traces, between 0 and 1. Turn tracing on briefly to see where latency goes, then set it back to 0. Read the current value with cassandra.nodetool_gettraceprobability.","description":"Set the fraction of requests this node traces, between 0 and 1. Turn tracing on briefly to see where latency goes, then set it back to 0. Read the current value with cassandra.nodetool_gettraceprobability.","kind":"exec","risk":"medium","side_effects":["Every traced request writes rows to the system_traces keyspace, adding write load and disk use.","Values above about 0.01 are heavy on a busy node; 1 traces every request.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"probability","type":"number","required":true,"description":"Fraction of requests to trace; 0 disables tracing.","validation":{"min":0,"max":1}}],"examples":[{"title":"Trace one request in a hundred","args":{"probability":0.01}},{"title":"Turn tracing back off","args":{"probability":0}}],"search_terms":[],"command":{"binary":"nodetool","argv":["settraceprobability","{{ args.probability }}"]}},{"id":"cassandra.nodetool_snapshot","title":"nodetool snapshot -t <name> [ks]","summary":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","description":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","kind":"exec","risk":"medium","side_effects":["Hard links created in each table's snapshots/<name>/ dir.","Disk usage grows as SSTables roll over (snapshot pins originals).","Use clearsnapshot to delete."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Backup snapshot","args":{"tag":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool snapshot -t \"$2\" \"$1\"; else nodetool snapshot -t \"$2\"; fi","emisar","{{ args.keyspace }}","{{ args.tag }}"]}},{"id":"cassandra.nodetool_status","title":"Cassandra node ring status","summary":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","description":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection to the local Cassandra node.","May fail if JMX auth is misconfigured.","Does not modify Cassandra data or cluster state."],"args":[{"name":"host","type":"string","required":false,"default":"127.0.0.1","description":"JMX host for nodetool.","validation":{"enum":["127.0.0.1","localhost"]}},{"name":"port","type":"integer","required":false,"default":7199,"description":"JMX port.","validation":{"allowed":[7199]}}],"examples":[{"title":"Check local Cassandra ring","args":{}}],"search_terms":["ring health","node down","cluster health"],"command":{"binary":"nodetool","argv":["-h","{{ args.host }}","-p","{{ args.port }}","status"]}},{"id":"cassandra.nodetool_statusautocompaction","title":"nodetool statusautocompaction [keyspace] [table]","summary":"Check whether automatic compaction is running — for the whole node, one keyspace, or one table. The read that catches a table left with autocompaction off after a bulk load.","description":"Check whether automatic compaction is running — for the whole node, one keyspace, or one table. The read that catches a table left with autocompaction off after a bulk load.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Keyspace to check; empty checks the whole node.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"table","type":"string","required":false,"default":"","description":"Table to check; needs keyspace, and empty checks every table in it.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Node-wide","args":{}},{"title":"One table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["statusautocompaction","{{ args.keyspace? }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_stop_compaction","title":"nodetool stop <operation>","summary":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","description":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","kind":"exec","risk":"high","side_effects":["In-flight ops of the named type are aborted.","SSTables in progress are abandoned (no partial result)."],"args":[{"name":"operation","type":"string","required":true,"description":"Operation type.","validation":{"enum":["COMPACTION","VALIDATION","CLEANUP","SCRUB","VERIFY","INDEX_BUILD","VIEW_BUILD","ANTICOMPACTION"]}}],"examples":[{"title":"Stop all compactions","args":{"operation":"COMPACTION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["stop","{{ args.operation }}"]}},{"id":"cassandra.nodetool_tablehistograms","title":"nodetool tablehistograms <ks> <table>","summary":"Show local-node read/write/sstable/partition-size histograms for one table.","description":"Show local-node read/write/sstable/partition-size histograms for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":["p99 latency","wide partitions"],"command":{"binary":"nodetool","argv":["tablehistograms","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_tablestats","title":"Cassandra table stats","summary":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","description":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Output can be large for clusters with many tables."],"args":[{"name":"keyspace","type":"string","required":false,"description":"Optional keyspace to scope to (omit for all keyspaces).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Inspect a single keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":["sstable count","tombstones","space used per table"],"command":{"binary":"nodetool","argv":["tablestats","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_toppartitions","title":"nodetool toppartitions <keyspace> <table> <duration>","summary":"Sample one table's traffic for a few seconds and print its busiest partitions by read and write frequency — the direct answer to \"which key is hot\" that cassandra.cqlsh_largest_partitions cannot give, since the biggest partition and the busiest one are rarely the same.","description":"Sample one table's traffic for a few seconds and print its busiest partitions by read and write frequency — the direct answer to \"which key is hot\" that cassandra.cqlsh_largest_partitions cannot give, since the biggest partition and the busiest one are rarely the same.","kind":"exec","risk":"medium","side_effects":["Turns on request sampling for the named table for the duration, then reports and stops.","Sampling adds bookkeeping to every read and write on that table while it runs.","Blocks for the whole sampling duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to sample.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"duration_ms","type":"integer","required":false,"default":5000,"description":"How long to sample, in milliseconds.","validation":{"min":1000,"max":60000}},{"name":"top_count","type":"integer","required":false,"default":10,"description":"How many partitions to list per sampler.","validation":{"min":1,"max":100}}],"examples":[{"title":"Busiest partitions over five seconds","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["toppartitions","-k","{{ args.top_count }}","--","{{ args.keyspace }}","{{ args.table }}","{{ args.duration_ms }}"]}},{"id":"cassandra.nodetool_tpstats","title":"Cassandra thread pool stats","summary":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","description":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect thread pool pressure","args":{}}],"search_terms":["dropped mutations","dropped messages"],"command":{"binary":"nodetool","argv":["tpstats"]}},{"id":"cassandra.nodetool_truncatehints","title":"nodetool truncatehints [endpoint]","summary":"Delete the hints this node is holding — all of them, or only those for one endpoint. The release valve when a hint backlog is filling the disk or targets a node that will never come back. The deleted writes are gone from this node's hint store, so the peers they were for need a repair.","description":"Delete the hints this node is holding — all of them, or only those for one endpoint. The release valve when a hint backlog is filling the disk or targets a node that will never come back. The deleted writes are gone from this node's hint store, so the peers they were for need a repair.","kind":"exec","risk":"high","side_effects":["Pending hints are deleted; the writes they carried are not delivered.","Every peer whose hints were dropped is left inconsistent until a repair runs.","Frees the disk the hint files were using."],"args":[{"name":"endpoint","type":"string","required":false,"default":"","description":"IP address or hostname whose hints to delete; empty deletes every pending hint on this node.","validation":{"pattern":"^([A-Za-z0-9._:-]{1,255})?$","max_length":255}}],"examples":[{"title":"Drop hints for one dead peer","args":{"endpoint":"10.1.4.7"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["truncatehints","--","{{ args.endpoint? }}"]}},{"id":"cassandra.nodetool_upgradesstables","title":"nodetool upgradesstables <keyspace> [table]","summary":"Rewrite SSTables that are still in an older on-disk format into the current one — the step after a major-version upgrade, and what lets the old format's read path be retired.","description":"Rewrite SSTables that are still in an older on-disk format into the current one — the step after a major-version upgrade, and what lets the old format's read path be retired.","kind":"exec","risk":"high","side_effects":["Rewrites every out-of-date SSTable of the named tables — sustained disk and CPU, and hours on a large node.","Needs free disk space for the rewritten files while it runs.","Does nothing when every file is already current, unless include_all is set."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to upgrade.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to upgrade; empty upgrades every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"include_all","type":"boolean","required":false,"default":false,"description":"Rewrite every SSTable, including files already in the current format."}],"examples":[{"title":"Upgrade one table's SSTables","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\n[ \"$INCLUDE_ALL\" = \"true\" ] && flags=\"-a\"\nset -- \"$KEYSPACE\"\n[ -n \"$TABLE\" ] && set -- \"$@\" \"$TABLE\"\nexec nodetool upgradesstables $flags -- \"$@\"\n"]}},{"id":"cassandra.nodetool_verify","title":"nodetool verify [ks] [table]","summary":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","description":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","kind":"exec","risk":"medium","side_effects":["Reads every SSTable for the targeted scope.","IO-heavy; CPU light."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Verify one ks","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool verify \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool verify \"$2\"; else nodetool verify; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_version","title":"nodetool version","summary":"Show the Cassandra version string for the node.","description":"Show the Cassandra version string for the node.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["version"]}},{"id":"cassandra.nodetool_viewbuildstatus","title":"nodetool viewbuildstatus <keyspace> <view>","summary":"Show whether a materialized view has finished building, per node. Exits non-zero while the build is still running, and names the nodes that are behind.","description":"Show whether a materialized view has finished building, per node. Exits non-zero while the build is still running, and names the nodes that are behind.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the view.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"view","type":"string","required":true,"description":"Materialized view name.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"View build progress","args":{"keyspace":"valorant_ks","view":"matches_by_player"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["viewbuildstatus","--","{{ args.keyspace }}","{{ args.view }}"]}}],"previous_versions":[{"version":"0.6.3","content_hash":"sha256:b15c4f8726c7255c07a405e2cc54222c959d01add776a69d96cc9209ee26df35","tarball_url":"https://registry.emisar.dev/v1/packs/cassandra/0.6.3/b15c4f8726c7255c07a405e2cc54222c959d01add776a69d96cc9209ee26df35/pack.tar.gz","actions":[{"id":"cassandra.analyze_disk_pressure","title":"Analyze Cassandra disk pressure","summary":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","description":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","kind":"script","risk":"low","side_effects":["Reads filesystem metadata (df, du counts).","Does not modify Cassandra data or configuration.","May create temporary files inside the runner's work directory."],"args":[{"name":"keyspace_filter","type":"string","required":false,"default":"","description":"Optional keyspace name to focus the analysis on.","validation":{"pattern":"^[a-zA-Z0-9_.*-]{0,80}$"}}],"examples":[{"title":"Analyze without keyspace filter","args":{}}],"search_terms":["disk full","running out of space"]},{"id":"cassandra.cqlsh_describe_keyspace","title":"cqlsh -e \"DESCRIBE KEYSPACE <ks>\"","summary":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","description":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace DDL","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACE '\"$1\"';' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_describe_schema","title":"cqlsh -e \"DESCRIBE SCHEMA\"","summary":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","description":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Full schema","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE SCHEMA;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_describe_table","title":"cqlsh -e \"DESCRIBE TABLE <ks>.<table>\"","summary":"Show the full DDL for one table — columns, primary key, and every table property (compaction, compression, gc_grace_seconds, caching, TTL defaults).","description":"Show the full DDL for one table — columns, primary key, and every table property (compaction, compression, gc_grace_seconds, caching, TTL defaults).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to describe.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table's DDL","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"DESCRIBE TABLE $1.$2;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.cqlsh_largest_partitions","title":"cqlsh -e \"SELECT * FROM system_views.max_partition_size\"","summary":"List each table's largest partition on this node, in mebibytes — the read that finds the wide partition behind slow reads, timeouts, or heap pressure.","description":"List each table's largest partition on this node, in mebibytes — the read that finds the wide partition behind slow reads, timeouts, or heap pressure.","kind":"exec","risk":"low","side_effects":["One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Largest partition per table","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, table_name, mebibytes FROM system_views.max_partition_size LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_list_keyspaces","title":"cqlsh -e \"DESCRIBE KEYSPACES\"","summary":"List all keyspaces.","description":"List all keyspaces.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Keyspaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_permissions","title":"cqlsh -e \"LIST ALL PERMISSIONS\"","summary":"List every permission granted to every role — who may read, write, or alter which keyspace and table. Needs CassandraAuthorizer and a login with permission to see other roles' grants.","description":"List every permission granted to every role — who may read, write, or alter which keyspace and table. Needs CassandraAuthorizer and a login with permission to see other roles' grants.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"All grants","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e 'LIST ALL PERMISSIONS;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_roles","title":"cqlsh -e \"LIST ROLES\"","summary":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","description":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Roles","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'LIST ROLES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_tables","title":"cqlsh -e \"SELECT table_name FROM system_schema.tables\"","summary":"List the tables in one keyspace by name — the cheap look-up before cassandra.cqlsh_describe_table, without the full DDL that cassandra.cqlsh_describe_keyspace dumps.","description":"List the tables in one keyspace by name — the cheap look-up before cassandra.cqlsh_describe_table, without the full DDL that cassandra.cqlsh_describe_keyspace dumps.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to list.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Tables in a keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT table_name FROM system_schema.tables WHERE keyspace_name = '$1';\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_repair_history","title":"cqlsh -e \"SELECT * FROM system_distributed.repair_history\"","summary":"List recent repair sessions the cluster recorded — keyspace, table, coordinator, start and finish time, and status. Shows what repaired and what failed, which cassandra.nodetool_repair's own output does not survive.","description":"List recent repair sessions the cluster recorded — keyspace, table, coordinator, start and finish time, and status. Shows what repaired and what failed, which cassandra.nodetool_repair's own output does not survive.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only.","A range scan of a cluster-wide table, bounded by the row limit."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Sessions to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent repair sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, columnfamily_name, coordinator, started_at, finished_at, status FROM system_distributed.repair_history LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_running_queries","title":"cqlsh -e \"SELECT * FROM system_views.queries\"","summary":"List the queries this node is executing right now, with how long each has been queued and running — the first look when a node is busy and nobody knows what it is doing. The query text includes literal values, so this returns application data and is approval-gated.","description":"List the queries this node is executing right now, with how long each has been queued and running — the first look when a node is busy and nobody knows what it is doing. The query text includes literal values, so this returns application data and is approval-gated.","kind":"exec","risk":"high","side_effects":["Query text includes the literals callers passed, so application data reaches the caller and the audit trail.","One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Queries to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"What this node is running now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT thread_id, queued_micros, running_micros, task FROM system_views.queries LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_select_by_key","title":"cqlsh -e \"SELECT * FROM <ks>.<table> WHERE <key> = <value>\"","summary":"Read the rows of one partition by its key — the \"does this row exist, and what does it hold\" lookup. Returns stored application data, so it is approval-gated. Use cassandra.nodetool_getendpoints for which replicas own the key without reading it.","description":"Read the rows of one partition by its key — the \"does this row exist, and what does it hold\" lookup. Returns stored application data, so it is approval-gated. Use cassandra.nodetool_getendpoints for which replicas own the key without reading it.","kind":"exec","risk":"high","side_effects":["Returns application data — whatever the partition holds reaches the caller and the audit trail.","A single-partition read on the coordinator, bounded by the row limit and the output cap.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key_column","type":"string","required":true,"description":"Partition key column to match.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key_value","type":"string","required":true,"description":"Key value, unquoted; the action quotes it according to key_type.","validation":{"pattern":"^[A-Za-z0-9._:+@-]{1,128}$","max_length":128}},{"name":"key_type","type":"string","required":false,"default":"text","description":"How to render the value in CQL — text quotes it, number and uuid pass it through bare.","validation":{"enum":["text","number","uuid"]}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Rows to return from the partition.","validation":{"min":1,"max":100}}],"examples":[{"title":"One partition by a text key","args":{"key_column":"match_id","key_value":"a41f2c7e","keyspace":"valorant_ks","table":"matches"}},{"title":"One partition by an integer key","args":{"key_column":"id","key_type":"number","key_value":"42","keyspace":"valorant_ks","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$KEY_TYPE\" in\n  text) predicate=\"$KEY_COLUMN = '$KEY_VALUE'\" ;;\n  number|uuid) predicate=\"$KEY_COLUMN = $KEY_VALUE\" ;;\n  *) printf 'unsupported key_type: %s\\n' \"$KEY_TYPE\" >&2; exit 2 ;;\nesac\nexec cqlsh -e \"SELECT * FROM $KEYSPACE.$TABLE WHERE $predicate LIMIT $LIMIT;\" \\\n  \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"\n"]}},{"id":"cassandra.cqlsh_select_rows","title":"cqlsh -e \"SELECT * FROM <ks>.<table> LIMIT <n>\"","summary":"Read a bounded sample of rows from one table. Returns stored application data, so it is approval-gated; use cassandra.cqlsh_select_by_key when you know the partition key, and cassandra.cqlsh_describe_table when you only need the shape.","description":"Read a bounded sample of rows from one table. Returns stored application data, so it is approval-gated; use cassandra.cqlsh_select_by_key when you know the partition key, and cassandra.cqlsh_describe_table when you only need the shape.","kind":"exec","risk":"high","side_effects":["Returns application data — whatever the table holds reaches the caller and the audit trail.","A range scan over the ring, bounded by the row limit and the output cap.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"limit","type":"integer","required":false,"default":10,"description":"Rows to return.","validation":{"min":1,"max":100}}],"examples":[{"title":"Ten rows from a table","args":{"keyspace":"valorant_ks","limit":10,"table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT * FROM $1.$2 LIMIT $3;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}","{{ args.table }}","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_settings","title":"cqlsh -e \"SELECT name, value FROM system_views.settings\"","summary":"Show the configuration this node is actually running, from the system_views.settings virtual table — cassandra.yaml as parsed at boot plus every runtime change made since. Pass a filter to narrow it to one area (compaction, stream, hinted_handoff); the unfiltered dump is over 500 rows.","description":"Show the configuration this node is actually running, from the system_views.settings virtual table — cassandra.yaml as parsed at boot plus every runtime change made since. Pass a filter to narrow it to one area (compaction, stream, hinted_handoff); the unfiltered dump is over 500 rows.","kind":"exec","risk":"medium","side_effects":["One CQL query against a virtual table; nothing is read from disk.","Read-only.","Cassandra 5.0 masks credential settings itself; on 4.x it returns keystore and truststore passwords in the clear, so this action redacts them on the way out."],"args":[{"name":"filter","type":"string","required":false,"default":"","description":"Case-insensitive substring of the setting name; empty returns every setting.","validation":{"pattern":"^[A-Za-z0-9_.]{0,64}$","max_length":64}}],"examples":[{"title":"Every runtime setting","args":{}},{"title":"Just the streaming settings","args":{"filter":"stream"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","settings=$(cqlsh -e 'SELECT name, value FROM system_views.settings;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\") || exit $?\n[ -z \"$FILTER\" ] && { printf '%s\\n' \"$settings\"; exit 0; }\nprintf '%s\\n' \"$settings\" | grep -F -i -e \"$FILTER\"\nmatched=$?\n[ \"$matched\" -eq 1 ] && { printf 'no setting name matched: %s\\n' \"$FILTER\"; exit 0; }\nexit \"$matched\"\n"]}},{"id":"cassandra.cqlsh_system_peers","title":"SELECT * FROM system.peers_v2","summary":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","description":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Peers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers_v2;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\" || cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_system_size_estimates","title":"SELECT * FROM system.size_estimates","summary":"Show per-table partition + size estimates from the gossiped size_estimates table.","description":"Show per-table partition + size estimates from the gossiped size_estimates table.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Size estimates","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT keyspace_name, table_name, range_start, range_end, mean_partition_size, partitions_count FROM system.size_estimates LIMIT 200;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_tombstones_per_read","title":"cqlsh -e \"SELECT * FROM system_views.tombstones_per_read\"","summary":"Show how many tombstones each table scans per read on this node (count, max, p50, p99) — the read that confirms a delete-heavy or TTL-heavy table is the reason queries are slow or failing.","description":"Show how many tombstones each table scans per read on this node (count, max, p50, p99) — the read that confirms a delete-heavy or TTL-heavy table is the reason queries are slow or failing.","kind":"exec","risk":"low","side_effects":["One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Tombstones scanned per read","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, table_name, count, max, p50th, p99th FROM system_views.tombstones_per_read LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.nodetool_assassinate","title":"nodetool assassinate <address>","summary":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","description":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","kind":"exec","risk":"critical","side_effects":["Node entry purged from gossip.","No data streaming — data that was on the node is gone.","Other replicas eventually catch up via repair."],"args":[{"name":"address","type":"string","required":true,"description":"IP address of the dead node.","validation":{"pattern":"^[0-9]{1,3}(\\.[0-9]{1,3}){3}$"}}],"examples":[{"title":"Remove permanently dead node","args":{"address":"10.0.0.42"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["assassinate","{{ args.address }}"]}},{"id":"cassandra.nodetool_bootstrap_resume","title":"nodetool bootstrap resume","summary":"Resume a bootstrap that failed part way, streaming only the ranges this node is still missing — the recovery when a joining node lost a stream and stopped short of joining the ring. Fails on a node that already finished bootstrapping.","description":"Resume a bootstrap that failed part way, streaming only the ranges this node is still missing — the recovery when a joining node lost a stream and stopped short of joining the ring. Fails on a node that already finished bootstrapping.","kind":"exec","risk":"high","side_effects":["Restarts streaming from the source replicas; expect sustained network and disk load until it completes.","Blocks until the bootstrap finishes or fails again.","The rate honours the caps set by cassandra.nodetool_setstreamthroughput and cassandra.nodetool_setinterdcstreamthroughput."],"args":[],"examples":[{"title":"Finish an interrupted bootstrap","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["bootstrap","resume"]}},{"id":"cassandra.nodetool_cleanup","title":"nodetool cleanup [ks]","summary":"Remove data no longer owned by this node (after a topology change). IO-heavy.","description":"Remove data no longer owned by this node (after a topology change). IO-heavy.","kind":"exec","risk":"high","side_effects":["SSTables rewritten without data that moved off this node.","Heavy IO + CPU; may take hours on large tables.","Free space requirement during cleanup."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Cleanup post-bootstrap","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool cleanup \"$1\"; else nodetool cleanup; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_clearsnapshot","title":"nodetool clearsnapshot -t <name>","summary":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","description":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","kind":"exec","risk":"high","side_effects":["Snapshot hard links removed.","Disk space reclaims as the underlying SSTables become orphaned."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag to delete.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Delete tag","args":{"tag":"old-backup"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clearsnapshot","-t","{{ args.tag }}"]}},{"id":"cassandra.nodetool_clientstats","title":"nodetool clientstats","summary":"List the clients connected to this node — count per user, driver, and protocol version. The read before cutting a node out of service, and the one that finds an old driver still talking to it.","description":"List the clients connected to this node — count per user, driver, and protocol version. The read before cutting a node out of service, and the one that finds an old driver still talking to it.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Connected clients","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clientstats"]}},{"id":"cassandra.nodetool_compact","title":"nodetool compact <ks> [table]","summary":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","description":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","kind":"exec","risk":"high","side_effects":["Heavy disk + CPU for the duration.","For STCS, creates one giant SSTable that is hard to compact later.","For LCS, may be fine."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Major-compact one table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool compact \"$2\" \"$1\"; else nodetool compact \"$2\"; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_compactionhistory","title":"nodetool compactionhistory","summary":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","description":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Recent compactions","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["compactionhistory"]}},{"id":"cassandra.nodetool_compactionstats","title":"Cassandra compaction statistics","summary":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","description":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect compaction backlog","args":{}}],"search_terms":["compactions backed up","compaction backlog","pending compactions"],"command":{"binary":"nodetool","argv":["compactionstats"]}},{"id":"cassandra.nodetool_datapaths","title":"nodetool datapaths","summary":"List the directories each table stores data in — the read that shows which disk a table actually lives on before you judge a full filesystem or a JBOD imbalance.","description":"List the directories each table stores data in — the read that shows which disk a table actually lives on before you judge a full filesystem or a JBOD imbalance.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Data directories per table","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["datapaths"]}},{"id":"cassandra.nodetool_decommission","title":"nodetool decommission","summary":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","description":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","kind":"exec","risk":"critical","side_effects":["All data streams to remaining replicas.","Heavy network + disk on this and peer nodes.","Node leaves the ring; tokens are reassigned.","Can take many hours on big datasets."],"args":[],"examples":[{"title":"Remove this node","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["decommission"]}},{"id":"cassandra.nodetool_describecluster","title":"nodetool describecluster","summary":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","description":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Cluster summary","args":{}}],"search_terms":["schema disagreement","schema mismatch"],"command":{"binary":"nodetool","argv":["describecluster"]}},{"id":"cassandra.nodetool_describering","title":"nodetool describering <keyspace>","summary":"Show token range → replica endpoint mapping for one keyspace.","description":"Show token range → replica endpoint mapping for one keyspace.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace's ring","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["describering","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_disableautocompaction","title":"nodetool disableautocompaction <keyspace> [table]","summary":"Stop automatic compaction for a keyspace or one table on this node — the usual move before a bulk load or a heavy backfill. Re-enable it with cassandra.nodetool_enableautocompaction as soon as the load is done.","description":"Stop automatic compaction for a keyspace or one table on this node — the usual move before a bulk load or a heavy backfill. Re-enable it with cassandra.nodetool_enableautocompaction as soon as the load is done.","kind":"exec","risk":"medium","side_effects":["New compactions stop being scheduled; compactions already running finish.","SSTable count and read latency grow for as long as it stays off, and disk use grows with them.","Runtime-only — a restart returns the node to automatic compaction."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to pause.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to pause; empty pauses every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Pause compaction on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disableautocompaction","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_disablebackup","title":"nodetool disablebackup","summary":"Stop incremental backup on this node — Cassandra stops hard-linking each new SSTable into the backups directory. Use when those links are filling the disk and the backup tooling is not clearing them.","description":"Stop incremental backup on this node — Cassandra stops hard-linking each new SSTable into the backups directory. Use when those links are filling the disk and the backup tooling is not clearing them.","kind":"exec","risk":"medium","side_effects":["New SSTables are no longer linked for backup, so incremental backups stop covering fresh data.","Links already created stay on disk.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[],"examples":[{"title":"Stop incremental backup","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablebackup"]}},{"id":"cassandra.nodetool_disablebinary","title":"nodetool disablebinary","summary":"Stop the native transport on this node — every CQL client is disconnected and no new client can connect to it. Gossip, streaming, and repair keep running, so the node stays a replica and keeps taking writes from its peers. Use to take one node out of client rotation without draining it.","description":"Stop the native transport on this node — every CQL client is disconnected and no new client can connect to it. Gossip, streaming, and repair keep running, so the node stays a replica and keeps taking writes from its peers. Use to take one node out of client rotation without draining it.","kind":"exec","risk":"critical","side_effects":["Connected clients are dropped and must reconnect elsewhere; a driver without other reachable nodes fails outright.","Requests this node was coordinating are lost, and the rest of the cluster carries its client load.","Reverse it with cassandra.nodetool_enablebinary; a restart also brings the transport back."],"args":[],"examples":[{"title":"Take this node out of client rotation","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablebinary"]}},{"id":"cassandra.nodetool_disablegossip","title":"nodetool disablegossip","summary":"Stop gossip on this node. Every peer marks it Down and stops routing replica traffic to it, while it keeps serving whatever clients are still connected — the isolation move for a node that is poisoning cluster state, and the way to strand a node if used carelessly.","description":"Stop gossip on this node. Every peer marks it Down and stops routing replica traffic to it, while it keeps serving whatever clients are still connected — the isolation move for a node that is poisoning cluster state, and the way to strand a node if used carelessly.","kind":"exec","risk":"critical","side_effects":["The cluster treats this node as Down — reads and writes route to other replicas, and hints pile up for it.","The node keeps its own client connections, so it can serve stale data while isolated.","Reverse it with cassandra.nodetool_enablegossip; the node then needs a repair for what it missed."],"args":[],"examples":[{"title":"Isolate this node from the ring","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablegossip"]}},{"id":"cassandra.nodetool_disablehandoff","title":"nodetool disablehandoff","summary":"Stop this node storing hints for unreachable peers. Different from cassandra.nodetool_pausehandoff, which keeps storing them and only stops delivery. Use when hint disk use is the problem, not delivery load.","description":"Stop this node storing hints for unreachable peers. Different from cassandra.nodetool_pausehandoff, which keeps storing them and only stops delivery. Use when hint disk use is the problem, not delivery load.","kind":"exec","risk":"medium","side_effects":["Writes destined for a down peer are no longer saved, so recovering that peer needs a repair.","Existing hints stay on disk and still replay.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[],"examples":[{"title":"Stop storing hints","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablehandoff"]}},{"id":"cassandra.nodetool_disablehintsfordc","title":"nodetool disablehintsfordc <datacenter>","summary":"Stop this node storing hints for one datacenter — the move when a remote datacenter is down for maintenance, or is being retired, and its hints would otherwise pile up on every local node.","description":"Stop this node storing hints for one datacenter — the move when a remote datacenter is down for maintenance, or is being retired, and its hints would otherwise pile up on every local node.","kind":"exec","risk":"medium","side_effects":["Writes destined for that datacenter's replicas stop being saved, so bringing it back needs a repair.","Hints for other datacenters are unaffected.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"datacenter","type":"string","required":true,"description":"Datacenter name as the snitch reports it.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Stop hints for a retiring datacenter","args":{"datacenter":"gcp-us-east1"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablehintsfordc","--","{{ args.datacenter }}"]}},{"id":"cassandra.nodetool_drain","title":"nodetool drain","summary":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","description":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","kind":"exec","risk":"critical","side_effects":["Node stops accepting writes immediately.","All memtables flushed.","Native + Thrift transports closed.","Only restart restores the node."],"args":[],"examples":[{"title":"Drain before restart","args":{}}],"search_terms":["safe shutdown","flush before restart"],"command":{"binary":"nodetool","argv":["drain"]}},{"id":"cassandra.nodetool_enableautocompaction","title":"nodetool enableautocompaction <keyspace> [table]","summary":"Resume automatic compaction for a keyspace or one table on this node after a cassandra.nodetool_disableautocompaction. Confirm with cassandra.nodetool_statusautocompaction.","description":"Resume automatic compaction for a keyspace or one table on this node after a cassandra.nodetool_disableautocompaction. Confirm with cassandra.nodetool_statusautocompaction.","kind":"exec","risk":"medium","side_effects":["Compaction resumes immediately and works off whatever backlog accumulated, which is CPU and disk heavy on a large one.","The backlog respects the cap set by cassandra.nodetool_setcompactionthroughput."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to resume.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to resume; empty resumes every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Resume compaction on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enableautocompaction","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_enablebackup","title":"nodetool enablebackup","summary":"Start incremental backup on this node — every new SSTable is hard-linked into the table's backups directory for an external backup job to collect. Confirm with cassandra.nodetool_service_status.","description":"Start incremental backup on this node — every new SSTable is hard-linked into the table's backups directory for an external backup job to collect. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Each new SSTable gains a hard link that only an external job removes, so disk use grows until something clears them.","Covers SSTables written from now on, not existing data; that needs cassandra.nodetool_snapshot."],"args":[],"examples":[{"title":"Start incremental backup","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablebackup"]}},{"id":"cassandra.nodetool_enablebinary","title":"nodetool enablebinary","summary":"Start the native transport on this node so CQL clients can connect again — the recovery from cassandra.nodetool_disablebinary. Confirm with cassandra.nodetool_service_status.","description":"Start the native transport on this node so CQL clients can connect again — the recovery from cassandra.nodetool_disablebinary. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"critical","side_effects":["Clients start connecting immediately, so a node that is not ready to serve reads takes traffic at once.","Check the node is Up/Normal with cassandra.nodetool_status first."],"args":[],"examples":[{"title":"Return this node to client rotation","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablebinary"]}},{"id":"cassandra.nodetool_enablegossip","title":"nodetool enablegossip","summary":"Start gossip on this node so the cluster sees it as Up again — the recovery from cassandra.nodetool_disablegossip. Confirm with cassandra.nodetool_service_status and cassandra.nodetool_status.","description":"Start gossip on this node so the cluster sees it as Up again — the recovery from cassandra.nodetool_disablegossip. Confirm with cassandra.nodetool_service_status and cassandra.nodetool_status.","kind":"exec","risk":"critical","side_effects":["Peers mark the node Up and resume routing replica traffic to it at once.","Writes it missed arrive as hints only inside the hint window; anything older needs a repair."],"args":[],"examples":[{"title":"Rejoin the ring","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablegossip"]}},{"id":"cassandra.nodetool_enablehandoff","title":"nodetool enablehandoff","summary":"Resume storing hints for unreachable peers after a cassandra.nodetool_disablehandoff. Confirm with cassandra.nodetool_service_status.","description":"Resume storing hints for unreachable peers after a cassandra.nodetool_disablehandoff. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Writes for a down peer are saved again, using disk for as long as the window set by cassandra.nodetool_setmaxhintwindow.","Nothing recovers the hints missed while storing was off; that gap needs a repair."],"args":[],"examples":[{"title":"Store hints again","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablehandoff"]}},{"id":"cassandra.nodetool_enablehintsfordc","title":"nodetool enablehintsfordc <datacenter>","summary":"Resume storing hints for one datacenter after a cassandra.nodetool_disablehintsfordc — the step that goes with bringing a remote datacenter back into service.","description":"Resume storing hints for one datacenter after a cassandra.nodetool_disablehintsfordc — the step that goes with bringing a remote datacenter back into service.","kind":"exec","risk":"medium","side_effects":["Writes for that datacenter's replicas are saved again while they are unreachable.","Nothing recovers the hints missed while it was off; that gap needs a repair."],"args":[{"name":"datacenter","type":"string","required":true,"description":"Datacenter name as the snitch reports it.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Store hints for a datacenter again","args":{"datacenter":"va1"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablehintsfordc","--","{{ args.datacenter }}"]}},{"id":"cassandra.nodetool_failuredetector","title":"nodetool failuredetector","summary":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","description":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Phi scores","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["failuredetector"]}},{"id":"cassandra.nodetool_flush","title":"nodetool flush [ks] [table]","summary":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","description":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","kind":"exec","risk":"high","side_effects":["Memtables for the targeted scope are flushed to disk.","Brief IO spike.","Commit log may be marked clean for the affected segments."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table (requires keyspace).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Flush one keyspace","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool flush \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool flush \"$2\"; else nodetool flush; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_garbagecollect","title":"nodetool garbagecollect <keyspace> [table]","summary":"Rewrite a table's SSTables to drop data already deleted or expired, without waiting for compaction to reach it — the way to reclaim space from a tombstone-heavy table on one node. Slower and heavier than letting compaction do the work.","description":"Rewrite a table's SSTables to drop data already deleted or expired, without waiting for compaction to reach it — the way to reclaim space from a tombstone-heavy table on one node. Slower and heavier than letting compaction do the work.","kind":"exec","risk":"high","side_effects":["Rewrites every SSTable of the named tables on this node — sustained disk read, write, and CPU for the duration.","Needs free disk space for the rewritten files while it runs.","Data past gc_grace_seconds is purged; nothing recoverable is lost."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to collect.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to collect; empty collects every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"granularity","type":"string","required":false,"default":"ROW","description":"ROW drops deleted partitions and rows; CELL also drops overwritten and deleted cells, at more cost.","validation":{"enum":["ROW","CELL"]}}],"examples":[{"title":"Reclaim space on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["garbagecollect","-g","{{ args.granularity }}","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_gcstats","title":"nodetool gcstats","summary":"Show garbage-collection statistics since the last call — pause counts, max and total elapsed time, and memory reclaimed. Long pauses here explain client timeouts that the latency histograms alone do not.","description":"Show garbage-collection statistics since the last call — pause counts, max and total elapsed time, and memory reclaimed. Long pauses here explain client timeouts that the latency histograms alone do not.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only.","Counters reset on read, so each call reports the interval since the previous one."],"args":[],"examples":[{"title":"GC since the last read","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gcstats"]}},{"id":"cassandra.nodetool_getbatchlogreplaythrottle","title":"nodetool getbatchlogreplaythrottle","summary":"Show the current batchlog replay throttle in KiB/s.","description":"Show the current batchlog replay throttle in KiB/s.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current batchlog replay throttle","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getbatchlogreplaythrottle"]}},{"id":"cassandra.nodetool_getcompactionthreshold","title":"nodetool getcompactionthreshold <keyspace> <table>","summary":"Show the min and max size-tiered compaction thresholds for one table.","description":"Show the min and max size-tiered compaction thresholds for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Thresholds for one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthreshold","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_getcompactionthroughput","title":"nodetool getcompactionthroughput","summary":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","description":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Compaction throughput","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthroughput"]}},{"id":"cassandra.nodetool_getconcurrency","title":"nodetool getconcurrency","summary":"List every request-processing stage on this node with its core and maximum pool size — the thread limits cassandra.nodetool_setconcurrency changes.","description":"List every request-processing stage on this node with its core and maximum pool size — the thread limits cassandra.nodetool_setconcurrency changes.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Stage thread limits","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrency"]}},{"id":"cassandra.nodetool_getconcurrentcompactors","title":"nodetool getconcurrentcompactors","summary":"Show the current concurrent_compactors setting.","description":"Show the current concurrent_compactors setting.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent compactors","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentcompactors"]}},{"id":"cassandra.nodetool_getconcurrentviewbuilders","title":"nodetool getconcurrentviewbuilders","summary":"Show how many materialized-view builds this node runs at once.","description":"Show how many materialized-view builds this node runs at once.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent view builders","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentviewbuilders"]}},{"id":"cassandra.nodetool_getendpoints","title":"nodetool getendpoints <ks> <table> <key>","summary":"Show which replicas own a specific partition key. Use to confirm read/write routing.","description":"Show which replicas own a specific partition key. Use to confirm read/write routing.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key (as a literal).","validation":{"pattern":"^[a-zA-Z0-9_:.][a-zA-Z0-9_\\-:.]{0,255}$"}}],"examples":[{"title":"Owning replicas","args":{"key":"user-1234","keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getendpoints","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getinterdcstreamthroughput","title":"nodetool getinterdcstreamthroughput","summary":"Show this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters. Reports \"unlimited\" when throttling is off.","description":"Show this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters. Reports \"unlimited\" when throttling is off.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to read, and in which unit. stream_megabits reports Mb/s, stream_mib the same cap in MiB/s, and entire_sstable_mib the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Cross-datacenter stream throughput in Mb/s","args":{}},{"title":"Cross-datacenter stream throughput in MiB/s","args":{"cap":"stream_mib"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"-d\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool getinterdcstreamthroughput \"$flag\"\n"]}},{"id":"cassandra.nodetool_getlogginglevels","title":"nodetool getlogginglevels","summary":"Show the current per-logger levels.","description":"Show the current per-logger levels.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Logger levels","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getlogginglevels"]}},{"id":"cassandra.nodetool_getmaxhintwindow","title":"nodetool getmaxhintwindow","summary":"Show how long this node keeps writing hints for an unreachable peer, in milliseconds.","description":"Show how long this node keeps writing hints for an unreachable peer, in milliseconds.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current hint window","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getmaxhintwindow"]}},{"id":"cassandra.nodetool_getseeds","title":"nodetool getseeds","summary":"List the seed nodes this node is currently using, excluding its own address — the running value, which drifts from cassandra.yaml after a cassandra.nodetool_reloadseeds or a seed-provider change.","description":"List the seed nodes this node is currently using, excluding its own address — the running value, which drifts from cassandra.yaml after a cassandra.nodetool_reloadseeds or a seed-provider change.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Seeds in use","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getseeds"]}},{"id":"cassandra.nodetool_getsnapshotthrottle","title":"nodetool getsnapshotthrottle","summary":"Show how many hard links per second snapshot and clearsnapshot may create. An unthrottled node reports the maximum long value rather than a word.","description":"Show how many hard links per second snapshot and clearsnapshot may create. An unthrottled node reports the maximum long value rather than a word.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current snapshot throttle","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getsnapshotthrottle"]}},{"id":"cassandra.nodetool_getsstables","title":"nodetool getsstables <keyspace> <table> <key>","summary":"List the SSTable files that hold one partition key — how many files a read of that key must touch. Empty output means the key's data is still in the memtable or absent.","description":"List the SSTable files that hold one partition key — how many files a read of that key must touch. Empty output means the key's data is still in the memtable or absent.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table holding the key.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key, in the string form nodetool accepts.","validation":{"pattern":"^[A-Za-z0-9._:+@-]{1,128}$","max_length":128}}],"examples":[{"title":"Files holding one key","args":{"key":"a41f2c7e","keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getsstables","--","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getstreamthroughput","title":"nodetool getstreamthroughput","summary":"Show this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Reports \"unlimited\" when throttling is off.","description":"Show this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Reports \"unlimited\" when throttling is off.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to read, and in which unit. stream_megabits reports Mb/s, stream_mib the same cap in MiB/s, and entire_sstable_mib the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Stream throughput in Mb/s","args":{}},{"title":"Stream throughput in MiB/s","args":{"cap":"stream_mib"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"-d\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool getstreamthroughput \"$flag\"\n"]}},{"id":"cassandra.nodetool_gettimeout","title":"nodetool gettimeout <type>","summary":"Show one of this node's request or internode timeouts, in milliseconds.","description":"Show one of this node's request or internode timeouts, in milliseconds.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"timeout_type","type":"string","required":true,"description":"Timeout to read.","validation":{"enum":["read","range","write","counterwrite","cascontention","truncate","internodeconnect","internodeuser","internodestreaminguser","misc"]}}],"examples":[{"title":"Current read timeout","args":{"timeout_type":"read"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gettimeout","{{ args.timeout_type }}"]}},{"id":"cassandra.nodetool_gettraceprobability","title":"nodetool gettraceprobability","summary":"Show the fraction of requests this node traces (0 = tracing off).","description":"Show the fraction of requests this node traces (0 = tracing off).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current trace probability","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gettraceprobability"]}},{"id":"cassandra.nodetool_gossipinfo","title":"nodetool gossipinfo","summary":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","description":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Gossip view","args":{}}],"search_terms":["node stuck joining"],"command":{"binary":"nodetool","argv":["gossipinfo"]}},{"id":"cassandra.nodetool_info","title":"nodetool info","summary":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","description":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"This node","args":{}}],"search_terms":["node uptime","heap usage"],"command":{"binary":"nodetool","argv":["info"]}},{"id":"cassandra.nodetool_invalidatecountercache","title":"nodetool invalidatecountercache","summary":"Drop the counter cache.","description":"Drop the counter cache.","kind":"exec","risk":"medium","side_effects":["Counter cache cleared.","Counter reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop counter cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecountercache"]}},{"id":"cassandra.nodetool_invalidatecredentialscache","title":"nodetool invalidatecredentialscache","summary":"Drop this node's cached credentials so a changed or revoked password takes effect now instead of when the cache expires. Needs PasswordAuthenticator.","description":"Drop this node's cached credentials so a changed or revoked password takes effect now instead of when the cache expires. Needs PasswordAuthenticator.","kind":"exec","risk":"medium","side_effects":["The next authentication for each role reads from the auth keyspace, so sign-ins are briefly slower.","Sessions already authenticated are not disconnected."],"args":[],"examples":[{"title":"Apply a password change now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecredentialscache"]}},{"id":"cassandra.nodetool_invalidatekeycache","title":"nodetool invalidatekeycache","summary":"Drop the key cache. Reads pay cold-cache cost until it warms.","description":"Drop the key cache. Reads pay cold-cache cost until it warms.","kind":"exec","risk":"medium","side_effects":["Key cache cleared.","Next reads must do bloom-filter + summary + index lookups."],"args":[],"examples":[{"title":"Drop key cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatekeycache"]}},{"id":"cassandra.nodetool_invalidatepermissionscache","title":"nodetool invalidatepermissionscache","summary":"Drop this node's cached permissions so a GRANT or REVOKE takes effect now instead of when the cache expires. Needs CassandraAuthorizer.","description":"Drop this node's cached permissions so a GRANT or REVOKE takes effect now instead of when the cache expires. Needs CassandraAuthorizer.","kind":"exec","risk":"medium","side_effects":["The next request per role and resource re-reads permissions, so queries are briefly slower.","Sessions already authorized keep running; only the next permission check is re-evaluated."],"args":[],"examples":[{"title":"Apply a REVOKE now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatepermissionscache"]}},{"id":"cassandra.nodetool_invalidaterolescache","title":"nodetool invalidaterolescache","summary":"Drop this node's cached roles so a role or membership change takes effect now instead of when the cache expires — the companion to cassandra.nodetool_invalidatepermissionscache after editing roles.","description":"Drop this node's cached roles so a role or membership change takes effect now instead of when the cache expires — the companion to cassandra.nodetool_invalidatepermissionscache after editing roles.","kind":"exec","risk":"medium","side_effects":["The next request per role re-reads the roles table, so queries are briefly slower.","Sessions already authenticated keep running under the reloaded role."],"args":[],"examples":[{"title":"Apply a role change now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterolescache"]}},{"id":"cassandra.nodetool_invalidaterowcache","title":"nodetool invalidaterowcache","summary":"Drop the row cache.","description":"Drop the row cache.","kind":"exec","risk":"medium","side_effects":["Row cache cleared.","Next reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop row cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterowcache"]}},{"id":"cassandra.nodetool_listpendinghints","title":"nodetool listpendinghints","summary":"List the hints this node is holding for peers that were unreachable — how much replay is waiting, and for whom. Reports plainly when there are none.","description":"List the hints this node is holding for peers that were unreachable — how much replay is waiting, and for whom. Reports plainly when there are none.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Hints waiting to replay","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listpendinghints"]}},{"id":"cassandra.nodetool_listsnapshots","title":"nodetool listsnapshots","summary":"List all snapshots on this node with size + creation timestamp.","description":"List all snapshots on this node with size + creation timestamp.","kind":"exec","risk":"low","side_effects":["Reads disk metadata.","Read-only."],"args":[],"examples":[{"title":"All snapshots","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listsnapshots"]}},{"id":"cassandra.nodetool_netstats","title":"nodetool netstats","summary":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","description":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Net stats","args":{}}],"search_terms":["streaming progress","streaming stuck","bootstrap progress"],"command":{"binary":"nodetool","argv":["netstats"]}},{"id":"cassandra.nodetool_pausehandoff","title":"nodetool pausehandoff","summary":"Pause hint delivery from this node. Hints keep accumulating; only the replay to peers stops — the move when a peer that just came back is being flooded. Resume with cassandra.nodetool_resumehandoff.","description":"Pause hint delivery from this node. Hints keep accumulating; only the replay to peers stops — the move when a peer that just came back is being flooded. Resume with cassandra.nodetool_resumehandoff.","kind":"exec","risk":"medium","side_effects":["Stored hints stop replaying; they stay on disk and grow.","Peers stay inconsistent until delivery resumes or a repair runs.","Runtime-only — a restart resumes delivery."],"args":[],"examples":[{"title":"Pause hint delivery","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["pausehandoff"]}},{"id":"cassandra.nodetool_proxyhistograms","title":"nodetool proxyhistograms","summary":"Show coordinator-side read/write latency histograms — what clients actually see.","description":"Show coordinator-side read/write latency histograms — what clients actually see.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Coordinator latencies","args":{}}],"search_terms":["p99 latency","latency percentiles","reads are slow","writes are slow"],"command":{"binary":"nodetool","argv":["proxyhistograms"]}},{"id":"cassandra.nodetool_rebuild","title":"nodetool rebuild [source_dc]","summary":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","description":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","kind":"exec","risk":"high","side_effects":["Heavy streaming workload.","Existing data on this node is NOT removed first.","Best run on a node that has empty data dirs."],"args":[{"name":"source_dc","type":"string","required":false,"default":"","description":"Source DC name (empty = any).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rebuild from us-east","args":{"source_dc":"us-east"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool rebuild \"$1\"; else nodetool rebuild; fi","emisar","{{ args.source_dc }}"]}},{"id":"cassandra.nodetool_rebuild_index","title":"nodetool rebuild_index <keyspace> <table> <index>","summary":"Rebuild one secondary index on this node from its base table — the fix when an index returns stale or missing rows after a restore, a scrub, or index corruption.","description":"Rebuild one secondary index on this node from its base table — the fix when an index returns stale or missing rows after a restore, a scrub, or index corruption.","kind":"exec","risk":"high","side_effects":["Reads the whole base table on this node and rewrites the index — sustained disk and CPU for the duration.","Queries using the index return incomplete results until the rebuild finishes."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Base table of the index.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"index","type":"string","required":true,"description":"Index name as the schema declares it.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Rebuild one index","args":{"index":"matches_player_idx","keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["rebuild_index","--","{{ args.keyspace }}","{{ args.table }}","{{ args.index }}"]}},{"id":"cassandra.nodetool_refresh","title":"nodetool refresh <keyspace> <table>","summary":"Load SSTable files that were placed into a table's data directory into the running node, with no restart — the last step of a file-level restore. Cassandra 5.0 prints a deprecation notice pointing at `nodetool import`, and still performs the load.","description":"Load SSTable files that were placed into a table's data directory into the running node, with no restart — the last step of a file-level restore. Cassandra 5.0 prints a deprecation notice pointing at `nodetool import`, and still performs the load.","kind":"exec","risk":"medium","side_effects":["The node starts serving whatever rows those files contain; a wrong file set changes query results.","Loading a large file set triggers compaction on the table."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table whose directory holds the new files.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Pick up restored SSTables","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["refresh","--","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_refreshsizeestimates","title":"nodetool refreshsizeestimates","summary":"Recompute the system.size_estimates table this node publishes. Run it when cassandra.cqlsh_system_size_estimates looks stale — Spark and analytics connectors split work from those numbers.","description":"Recompute the system.size_estimates table this node publishes. Run it when cassandra.cqlsh_system_size_estimates looks stale — Spark and analytics connectors split work from those numbers.","kind":"exec","risk":"medium","side_effects":["Rewrites this node's size_estimates rows; it reads SSTable metadata, not data.","Cheap on a small node, noticeable on one with many tables."],"args":[],"examples":[{"title":"Recompute size estimates","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["refreshsizeestimates"]}},{"id":"cassandra.nodetool_reloadlocalschema","title":"nodetool reloadlocalschema","summary":"Reload this node's schema from its own system tables — the first, cheap remedy when cassandra.nodetool_describecluster reports this node on a different schema version from the rest.","description":"Reload this node's schema from its own system tables — the first, cheap remedy when cassandra.nodetool_describecluster reports this node on a different schema version from the rest.","kind":"exec","risk":"medium","side_effects":["Rebuilds the in-memory schema from local system tables; it pulls nothing from peers and drops nothing.","Brief pause on schema-dependent work while it reloads."],"args":[],"examples":[{"title":"Reload the local schema","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadlocalschema"]}},{"id":"cassandra.nodetool_reloadseeds","title":"nodetool reloadseeds","summary":"Re-read the seed list from the seed provider without restarting — the step after editing seeds in cassandra.yaml, typically while replacing seed nodes. Read the result back with cassandra.nodetool_getseeds.","description":"Re-read the seed list from the seed provider without restarting — the step after editing seeds in cassandra.yaml, typically while replacing seed nodes. Read the result back with cassandra.nodetool_getseeds.","kind":"exec","risk":"medium","side_effects":["Replaces the in-memory seed list; gossip with current peers is unaffected.","Prints the new list, or says the provider returned no remote addresses."],"args":[],"examples":[{"title":"Re-read the seed list","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadseeds"]}},{"id":"cassandra.nodetool_reloadssl","title":"nodetool reloadssl","summary":"Reload the keystore and truststore from disk so a renewed certificate takes effect without a restart — the step that finishes a certificate rotation on a live node.","description":"Reload the keystore and truststore from disk so a renewed certificate takes effect without a restart — the step that finishes a certificate rotation on a live node.","kind":"exec","risk":"medium","side_effects":["New connections use the reloaded material; connections already established keep their current session.","A keystore that is unreadable or has the wrong password fails here, before it can break new connections."],"args":[],"examples":[{"title":"Pick up a renewed certificate","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadssl"]}},{"id":"cassandra.nodetool_relocatesstables","title":"nodetool relocatesstables <keyspace> <table>","summary":"Move a table's SSTables onto the disk that owns their token range — the fix after adding or replacing a data directory on a node that spreads data across several disks. A no-op on a node with one data directory.","description":"Move a table's SSTables onto the disk that owns their token range — the fix after adding or replacing a data directory on a node that spreads data across several disks. A no-op on a node with one data directory.","kind":"exec","risk":"high","side_effects":["Rewrites SSTables onto their correct disk — sustained disk read and write for the duration.","Needs free space on the target disk while files are moved."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to relocate.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to relocate.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Rebalance one table across disks","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["relocatesstables","--","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_removenode","title":"nodetool removenode <host-id>","summary":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","description":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","kind":"exec","risk":"critical","side_effects":["Other replicas stream the dead node's data to their successors.","Heavy network + disk during stream.","Token range reassigned permanently."],"args":[{"name":"host_id","type":"string","required":true,"description":"Host ID UUID (from nodetool status).","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Remove a down node","args":{"host_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["remove dead node"],"command":{"binary":"nodetool","argv":["removenode","{{ args.host_id }}"]}},{"id":"cassandra.nodetool_repair","title":"Cassandra repair","summary":"Wrap `nodetool repair`.","description":"Wrap `nodetool repair`. The most dangerous \"normal\" operation — repair reconciles data between replicas, can take hours, produces significant cluster-wide load, may interact poorly with TTL/tombstone-heavy tables, and can worsen latency on every replica it touches. Always inspect ring status, compactions, disk, and logs first. Prefer mode=preview — a dry run that estimates the repair without performing it (requires Cassandra 4.0+) — before a real repair. Refuse to proceed if the ring has DN/UJ/UL/UM nodes.","kind":"exec","risk":"high","side_effects":["Repair coordinates with replicas across the cluster.","Generates significant network, CPU, and disk I/O.","Schedules anti-compaction and validation tasks.","Can run for minutes to hours depending on dataset size.","May worsen latency on the local node and on replica nodes for the duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to repair.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional single table to repair (empty = whole keyspace).","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"mode","type":"string","required":false,"default":"preview","description":"Repair mode.","validation":{"enum":["preview","full","incremental"]}},{"name":"primary_range","type":"boolean","required":false,"default":true,"description":"Restrict to the primary token range (recommended)."},{"name":"parallelism","type":"string","required":false,"default":"sequential","description":"Parallelism mode.","validation":{"enum":["sequential","parallel","dc_parallel"]}}],"examples":[{"title":"Dry-run repair preview on one keyspace","args":{"keyspace":"valorant_ks","mode":"preview"}}],"search_terms":["anti-entropy","inconsistent replicas","data consistency"],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\ncase \"$MODE\" in\n  preview) flags=\"--preview\" ;;\n  full) flags=\"-full\" ;;\n  # Incremental is nodetool's own default on 4.x and 5.x and has no flag\n  # of its own (-inc went away after 3.x). Named anyway: falling through\n  # meant the operator asked for incremental and silently got whatever\n  # this node's version defaults to, and the next enum value added here\n  # would have inherited the same silence.\n  incremental) flags=\"\" ;;\n  *) printf 'unsupported repair mode: %s\\n' \"$MODE\" >&2; exit 2 ;;\nesac\n[ \"$PR\" = \"true\" ] && flags=\"$flags -pr\"\ncase \"$PAR\" in\n  sequential) flags=\"$flags -seq\" ;;\n  dc_parallel) flags=\"$flags -dcpar\" ;;\nesac\nset -- \"$KS\"\n[ -n \"$TBL\" ] && set -- \"$@\" \"$TBL\"\nexec nodetool repair $flags \"$@\"\n"]}},{"id":"cassandra.nodetool_repair_admin_list","title":"nodetool repair_admin list","summary":"List the incremental repair sessions this node knows about. A session stuck in a non-finished state is what keeps SSTables pending repair and blocks later repairs; \"no sessions\" is the healthy answer.","description":"List the incremental repair sessions this node knows about. A session stuck in a non-finished state is what keeps SSTables pending repair and blocks later repairs; \"no sessions\" is the healthy answer.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"include_completed","type":"boolean","required":false,"default":false,"description":"Include finished sessions as well as the ones still in flight."}],"examples":[{"title":"Sessions still in flight","args":{}},{"title":"Every recorded session","args":{"include_completed":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ \"$ALL\" = \"true\" ] && exec nodetool repair_admin list --all\nexec nodetool repair_admin list\n"]}},{"id":"cassandra.nodetool_replaybatchlog","title":"nodetool replaybatchlog","summary":"Replay this node's batchlog now and wait for it to finish, instead of waiting for the periodic sweep — the step that clears batches left behind after a node came back from an outage.","description":"Replay this node's batchlog now and wait for it to finish, instead of waiting for the periodic sweep — the step that clears batches left behind after a node came back from an outage.","kind":"exec","risk":"medium","side_effects":["Replays batched writes to their replicas, adding write load until the backlog clears.","Blocks until the replay finishes.","The rate honours the cap set by cassandra.nodetool_setbatchlogreplaythrottle."],"args":[],"examples":[{"title":"Clear the batchlog now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["replaybatchlog"]}},{"id":"cassandra.nodetool_resumehandoff","title":"nodetool resumehandoff","summary":"Resume hint delivery from this node after a cassandra.nodetool_pausehandoff. Confirm with cassandra.nodetool_service_status.","description":"Resume hint delivery from this node after a cassandra.nodetool_pausehandoff. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Stored hints start replaying to their peers immediately.","A large backlog puts load on this node and on the peers receiving it; cap it with cassandra.nodetool_sethintedhandoffthrottlekb."],"args":[],"examples":[{"title":"Resume hint delivery","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["resumehandoff"]}},{"id":"cassandra.nodetool_ring","title":"nodetool ring [keyspace]","summary":"Show the token ring with owner host per token.","description":"Show the token ring with owner host per token.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (default — all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Ring","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool ring \"$1\"; else nodetool ring; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_scrub","title":"nodetool scrub <keyspace> [table]","summary":"Rebuild a table's SSTables on this node, validating each row as it goes — the repair for corrupt files reported in the log. Snapshots first by default, so the pre-scrub files remain until you clear that snapshot.","description":"Rebuild a table's SSTables on this node, validating each row as it goes — the repair for corrupt files reported in the log. Snapshots first by default, so the pre-scrub files remain until you clear that snapshot.","kind":"exec","risk":"high","side_effects":["Rewrites every SSTable of the named tables — sustained disk and CPU for the duration.","Takes a snapshot first, which occupies disk until cassandra.nodetool_clearsnapshot removes it.","With skip_corrupted, unreadable rows are dropped instead of failing the scrub; that data is gone from this node and needs a repair."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to scrub.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to scrub; empty scrubs every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"skip_corrupted","type":"boolean","required":false,"default":false,"description":"Drop rows that cannot be read instead of stopping at them."}],"examples":[{"title":"Scrub one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\n[ \"$SKIP_CORRUPTED\" = \"true\" ] && flags=\"-s\"\nset -- \"$KEYSPACE\"\n[ -n \"$TABLE\" ] && set -- \"$@\" \"$TABLE\"\nexec nodetool scrub $flags -- \"$@\"\n"]}},{"id":"cassandra.nodetool_service_status","title":"nodetool statusbinary / statusgossip / statusbackup / statushandoff","summary":"Check what this node currently has switched on — native transport (client traffic), gossip, incremental backup, and hinted handoff — in one call. The read to take before and after any of the enable/disable actions.","description":"Check what this node currently has switched on — native transport (client traffic), gossip, incremental backup, and hinted handoff — in one call. The read to take before and after any of the enable/disable actions.","kind":"exec","risk":"low","side_effects":["Four JMX calls.","Read-only."],"args":[],"examples":[{"title":"What is switched on","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","for check in statusbinary statusgossip statusbackup statushandoff; do\n  printf '%s: ' \"$check\"\n  nodetool \"$check\" || exit $?\ndone\n"]}},{"id":"cassandra.nodetool_setbatchlogreplaythrottle","title":"nodetool setbatchlogreplaythrottle <KiB/s>","summary":"Set the batchlog replay throttle in KiB/s. Lower it when replaying batches after an outage is adding load to an already busy node; 0 disables throttling. Read the current value with cassandra.nodetool_getbatchlogreplaythrottle.","description":"Set the batchlog replay throttle in KiB/s. Lower it when replaying batches after an outage is adding load to an already busy node; 0 disables throttling. Read the current value with cassandra.nodetool_getbatchlogreplaythrottle.","kind":"exec","risk":"medium","side_effects":["Applies to replay work that starts after the change.","Cassandra reduces the rate proportionally to the number of nodes in the cluster.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"kb_per_sec","type":"integer","required":true,"description":"Throttle in KiB/s; 0 disables throttling.","validation":{"min":0,"max":1048576}}],"examples":[{"title":"Halve the default replay rate","args":{"kb_per_sec":512}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setbatchlogreplaythrottle","{{ args.kb_per_sec }}"]}},{"id":"cassandra.nodetool_setcachecapacity","title":"nodetool setcachecapacity <key MB> <row MB> <counter MB>","summary":"Set the key, row, and counter cache capacities in MB. All three are set in one call, so pass the current value for any cache you are not changing; 0 disables a cache. cassandra.nodetool_info reports the capacities in use.","description":"Set the key, row, and counter cache capacities in MB. All three are set in one call, so pass the current value for any cache you are not changing; 0 disables a cache. cassandra.nodetool_info reports the capacities in use.","kind":"exec","risk":"medium","side_effects":["Shrinking a cache evicts entries immediately, so reads run cold until it refills.","The key and counter caches live on the JVM heap — oversizing them adds GC pressure on the node.","Runtime-only — a restart returns the node to its cassandra.yaml values."],"args":[{"name":"key_cache_mb","type":"integer","required":true,"description":"Key cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}},{"name":"row_cache_mb","type":"integer","required":true,"description":"Row cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}},{"name":"counter_cache_mb","type":"integer","required":true,"description":"Counter cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}}],"examples":[{"title":"512 MB key cache, row cache off, 128 MB counter cache","args":{"counter_cache_mb":128,"key_cache_mb":512,"row_cache_mb":0}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcachecapacity","{{ args.key_cache_mb }}","{{ args.row_cache_mb }}","{{ args.counter_cache_mb }}"]}},{"id":"cassandra.nodetool_setcompactionthreshold","title":"nodetool setcompactionthreshold <keyspace> <table> <min> <max>","summary":"Set the min and max SSTable count that triggers size-tiered compaction for one table. Raising the minimum makes the table compact less often and keeps more SSTables; lowering it compacts sooner. Read the current pair with cassandra.nodetool_getcompactionthreshold.","description":"Set the min and max SSTable count that triggers size-tiered compaction for one table. Raising the minimum makes the table compact less often and keeps more SSTables; lowering it compacts sooner. Read the current pair with cassandra.nodetool_getcompactionthreshold.","kind":"exec","risk":"medium","side_effects":["Applies to this table on this node only, and takes effect on the next compaction decision.","A higher minimum leaves more SSTables per read until the next compaction.","Runtime-only — a restart returns the table to its schema value."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to change.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"min_threshold","type":"integer","required":true,"description":"SSTables of one size tier needed before compaction starts (nodetool requires at least 2).","validation":{"min":2,"max":1000}},{"name":"max_threshold","type":"integer","required":true,"description":"Most SSTables compacted at once; must not be below min_threshold.","validation":{"min":2,"max":1000}}],"examples":[{"title":"Standard size-tiered thresholds","args":{"keyspace":"valorant_ks","max_threshold":32,"min_threshold":4,"table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthreshold","{{ args.keyspace }}","{{ args.table }}","{{ args.min_threshold }}","{{ args.max_threshold }}"]}},{"id":"cassandra.nodetool_setcompactionthroughput","title":"nodetool setcompactionthroughput <MB/s>","summary":"Set max compaction throughput. 0 = unlimited (use carefully).","description":"Set max compaction throughput. 0 = unlimited (use carefully).","kind":"exec","risk":"medium","side_effects":["In-flight + future compactions throttled to the new cap.","Lower values reduce IO pressure but grow SSTable count."],"args":[{"name":"mb_per_sec","type":"integer","required":true,"description":"MB/s; 0 = unlimited.","validation":{"min":0,"max":10000}}],"examples":[{"title":"Throttle to 16 MB/s","args":{"mb_per_sec":16}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthroughput","{{ args.mb_per_sec }}"]}},{"id":"cassandra.nodetool_setconcurrency","title":"nodetool setconcurrency <stage> <max>","summary":"Set the maximum number of threads one request-processing stage may use. Lower a stage to stop it crowding out the rest of the node, raise it when a stage is the bottleneck. List the stages and their current sizes with cassandra.nodetool_getconcurrency.","description":"Set the maximum number of threads one request-processing stage may use. Lower a stage to stop it crowding out the rest of the node, raise it when a stage is the bottleneck. List the stages and their current sizes with cassandra.nodetool_getconcurrency.","kind":"exec","risk":"medium","side_effects":["Applies immediately; work already queued on the stage runs under the new limit.","Starving a stage that serves live traffic (MUTATION, READ) shows up as client timeouts.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"stage","type":"string","required":true,"description":"Stage to resize, under the name nodetool accepts — MUTATION is the MutationStage that cassandra.nodetool_getconcurrency prints.","validation":{"enum":["READ","MUTATION","COUNTER_MUTATION","VIEW_MUTATION","GOSSIP","REQUEST_RESPONSE","ANTI_ENTROPY","MIGRATION","MISC","TRACING","INTERNAL_RESPONSE","IMMEDIATE","PAXOS_REPAIR"]}},{"name":"max_concurrency","type":"integer","required":true,"description":"Maximum threads for the stage.","validation":{"min":1,"max":1024}}],"examples":[{"title":"Hold write threads at 16","args":{"max_concurrency":16,"stage":"MUTATION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrency","{{ args.stage }}","{{ args.max_concurrency }}"]}},{"id":"cassandra.nodetool_setconcurrentcompactors","title":"nodetool setconcurrentcompactors <count>","summary":"Set how many compactions this node runs at once. Raise it to work off a compaction backlog, lower it to give CPU and disk back to reads and writes. Read the current value with cassandra.nodetool_getconcurrentcompactors.","description":"Set how many compactions this node runs at once. Raise it to work off a compaction backlog, lower it to give CPU and disk back to reads and writes. Read the current value with cassandra.nodetool_getconcurrentcompactors.","kind":"exec","risk":"medium","side_effects":["New compactions pick up the limit; compactions already running are not stopped.","Each compactor consumes CPU and disk IO, and shares the cap set by cassandra.nodetool_setcompactionthroughput.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"count","type":"integer","required":true,"description":"Number of concurrent compactors.","validation":{"min":1,"max":128}}],"examples":[{"title":"Allow four concurrent compactions","args":{"count":4}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrentcompactors","{{ args.count }}"]}},{"id":"cassandra.nodetool_setconcurrentviewbuilders","title":"nodetool setconcurrentviewbuilders <count>","summary":"Set how many materialized-view builds this node runs at once. Lower it when a view build is competing with live traffic, raise it to finish a build sooner. Read the current value with cassandra.nodetool_getconcurrentviewbuilders.","description":"Set how many materialized-view builds this node runs at once. Lower it when a view build is competing with live traffic, raise it to finish a build sooner. Read the current value with cassandra.nodetool_getconcurrentviewbuilders.","kind":"exec","risk":"medium","side_effects":["New view builds pick up the limit; builds already running are not stopped.","Each builder reads base-table data and writes view rows, adding CPU and disk IO.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"count","type":"integer","required":true,"description":"Number of concurrent view builders.","validation":{"min":1,"max":128}}],"examples":[{"title":"Hold view builds to one at a time","args":{"count":1}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrentviewbuilders","{{ args.count }}"]}},{"id":"cassandra.nodetool_sethintedhandoffthrottlekb","title":"nodetool sethintedhandoffthrottlekb <KiB/s>","summary":"Set the hinted-handoff delivery throttle in KiB/s, per delivery thread. Lower it when a peer coming back online is being flooded with replayed hints; raise it to clear a hint backlog faster.","description":"Set the hinted-handoff delivery throttle in KiB/s, per delivery thread. Lower it when a peer coming back online is being flooded with replayed hints; raise it to clear a hint backlog faster.","kind":"exec","risk":"medium","side_effects":["Applies to hint deliveries that start after the change.","Cassandra divides the rate across live peers, so the effective per-peer rate is lower in a large cluster.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"kb_per_sec","type":"integer","required":true,"description":"Throttle in KiB/s, per delivery thread.","validation":{"min":1,"max":1048576}}],"examples":[{"title":"Halve the default hint delivery rate","args":{"kb_per_sec":512}}],"search_terms":[],"command":{"binary":"nodetool","argv":["sethintedhandoffthrottlekb","{{ args.kb_per_sec }}"]}},{"id":"cassandra.nodetool_setinterdcstreamthroughput","title":"nodetool setinterdcstreamthroughput <value>","summary":"Set this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters during rebuild, bootstrap, and repair. Protects a shared or metered inter-datacenter link while local streaming keeps its own cap from cassandra.nodetool_setstreamthroughput. 0 disables throttling.","description":"Set this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters during rebuild, bootstrap, and repair. Protects a shared or metered inter-datacenter link while local streaming keeps its own cap from cassandra.nodetool_setstreamthroughput. 0 disables throttling.","kind":"exec","risk":"medium","side_effects":["Applies immediately, to streams already in flight as well as new ones.","A cap under the current rate slows a running cross-datacenter rebuild; 0 lets it saturate the link.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"value","type":"integer","required":true,"description":"Cap in the unit named by cap; 0 disables throttling.","validation":{"min":0,"max":100000}},{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to set, and in which unit. stream_megabits is nodetool's own default (Mb/s); stream_mib is the same cap in MiB/s; entire_sstable_mib is the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Hold cross-datacenter streaming to 800 Mb/s","args":{"value":800}},{"title":"Hold cross-datacenter streaming to 40 MiB/s","args":{"cap":"stream_mib","value":40}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool setinterdcstreamthroughput $flag -- \"$VALUE\"\n"]}},{"id":"cassandra.nodetool_setlogginglevel","title":"nodetool setlogginglevel <logger> <level>","summary":"Set one logger's level. Use empty logger to reset all to the configured defaults.","description":"Set one logger's level. Use empty logger to reset all to the configured defaults.","kind":"exec","risk":"medium","side_effects":["Logger level changes immediately.","DEBUG/TRACE levels can dramatically increase log volume."],"args":[{"name":"logger","type":"string","required":true,"description":"Logger name (e.g. org.apache.cassandra.db, or \"root\").","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"level","type":"string","required":true,"description":"Level.","validation":{"enum":["TRACE","DEBUG","INFO","WARN","ERROR","OFF"]}}],"examples":[{"title":"Set DB layer to DEBUG","args":{"level":"DEBUG","logger":"org.apache.cassandra.db"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setlogginglevel","{{ args.logger }}","{{ args.level }}"]}},{"id":"cassandra.nodetool_setmaxhintwindow","title":"nodetool setmaxhintwindow <ms>","summary":"Set how long this node keeps writing hints for an unreachable peer, in milliseconds. Raise it to carry a peer through a longer maintenance window without a repair afterwards; 0 stops hint storage entirely. Read the current window with cassandra.nodetool_getmaxhintwindow.","description":"Set how long this node keeps writing hints for an unreachable peer, in milliseconds. Raise it to carry a peer through a longer maintenance window without a repair afterwards; 0 stops hint storage entirely. Read the current window with cassandra.nodetool_getmaxhintwindow.","kind":"exec","risk":"medium","side_effects":["A longer window stores more hints on disk and lengthens replay when the peer returns.","Writes made while a peer is down past the window are only recoverable by repair.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"window_ms","type":"integer","required":true,"description":"Hint window in milliseconds; 0 stops storing hints.","validation":{"min":0,"max":604800000}}],"examples":[{"title":"Hold hints for six hours","args":{"window_ms":21600000}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setmaxhintwindow","{{ args.window_ms }}"]}},{"id":"cassandra.nodetool_setsnapshotthrottle","title":"nodetool setsnapshotthrottle <links/s>","summary":"Set how many hard links per second snapshot and clearsnapshot may create. Lower it when taking a snapshot of a large node stalls the filesystem; 0 disables throttling. Read the current value with cassandra.nodetool_getsnapshotthrottle.","description":"Set how many hard links per second snapshot and clearsnapshot may create. Lower it when taking a snapshot of a large node stalls the filesystem; 0 disables throttling. Read the current value with cassandra.nodetool_getsnapshotthrottle.","kind":"exec","risk":"medium","side_effects":["Applies to snapshot work that starts after the change.","A low rate makes cassandra.nodetool_snapshot and cassandra.nodetool_clearsnapshot take proportionally longer on a table with many SSTables.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"links_per_sec","type":"integer","required":true,"description":"Hard links per second; 0 disables throttling.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Cap snapshot link creation","args":{"links_per_sec":200}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setsnapshotthrottle","{{ args.links_per_sec }}"]}},{"id":"cassandra.nodetool_setstreamthroughput","title":"nodetool setstreamthroughput <value>","summary":"Set this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Covers every stream the node sends; cross-datacenter streams are additionally capped by cassandra.nodetool_setinterdcstreamthroughput. 0 disables throttling.","description":"Set this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Covers every stream the node sends; cross-datacenter streams are additionally capped by cassandra.nodetool_setinterdcstreamthroughput. 0 disables throttling.","kind":"exec","risk":"medium","side_effects":["Applies immediately, to streams already in flight as well as new ones.","A cap under the current rate slows a running rebuild or repair; 0 lets streaming saturate the link.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"value","type":"integer","required":true,"description":"Cap in the unit named by cap; 0 disables throttling.","validation":{"min":0,"max":100000}},{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to set, and in which unit. stream_megabits is nodetool's own default (Mb/s); stream_mib is the same cap in MiB/s; entire_sstable_mib is the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Throttle streaming to 200 Mb/s","args":{"value":200}},{"title":"Throttle streaming to 64 MiB/s","args":{"cap":"stream_mib","value":64}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool setstreamthroughput $flag -- \"$VALUE\"\n"]}},{"id":"cassandra.nodetool_settimeout","title":"nodetool settimeout <type> <ms>","summary":"Set one of this node's request or internode timeouts, in milliseconds. Raise a timeout to ride out a slow period instead of failing queries, or lower it to fail fast. Read the current value with cassandra.nodetool_gettimeout.","description":"Set one of this node's request or internode timeouts, in milliseconds. Raise a timeout to ride out a slow period instead of failing queries, or lower it to fail fast. Read the current value with cassandra.nodetool_gettimeout.","kind":"exec","risk":"medium","side_effects":["Applies to requests that start after the change; requests in flight keep the old timeout.","A raised timeout holds threads and memory longer under load, which can turn a slow node into an unresponsive one.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"timeout_type","type":"string","required":true,"description":"Timeout to change.","validation":{"enum":["read","range","write","counterwrite","cascontention","truncate","internodeconnect","internodeuser","internodestreaminguser","misc"]}},{"name":"timeout_ms","type":"integer","required":true,"description":"Timeout in milliseconds. nodetool also takes 0, which for a request timeout means every request of that type fails at once rather than \"no limit\", so this action starts at 1.","validation":{"min":1,"max":3600000}}],"examples":[{"title":"Give reads two more seconds","args":{"timeout_ms":7000,"timeout_type":"read"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["settimeout","{{ args.timeout_type }}","{{ args.timeout_ms }}"]}},{"id":"cassandra.nodetool_settraceprobability","title":"nodetool settraceprobability <probability>","summary":"Set the fraction of requests this node traces, between 0 and 1. Turn tracing on briefly to see where latency goes, then set it back to 0. Read the current value with cassandra.nodetool_gettraceprobability.","description":"Set the fraction of requests this node traces, between 0 and 1. Turn tracing on briefly to see where latency goes, then set it back to 0. Read the current value with cassandra.nodetool_gettraceprobability.","kind":"exec","risk":"medium","side_effects":["Every traced request writes rows to the system_traces keyspace, adding write load and disk use.","Values above about 0.01 are heavy on a busy node; 1 traces every request.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"probability","type":"number","required":true,"description":"Fraction of requests to trace; 0 disables tracing.","validation":{"min":0,"max":1}}],"examples":[{"title":"Trace one request in a hundred","args":{"probability":0.01}},{"title":"Turn tracing back off","args":{"probability":0}}],"search_terms":[],"command":{"binary":"nodetool","argv":["settraceprobability","{{ args.probability }}"]}},{"id":"cassandra.nodetool_snapshot","title":"nodetool snapshot -t <name> [ks]","summary":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","description":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","kind":"exec","risk":"medium","side_effects":["Hard links created in each table's snapshots/<name>/ dir.","Disk usage grows as SSTables roll over (snapshot pins originals).","Use clearsnapshot to delete."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Backup snapshot","args":{"tag":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool snapshot -t \"$2\" \"$1\"; else nodetool snapshot -t \"$2\"; fi","emisar","{{ args.keyspace }}","{{ args.tag }}"]}},{"id":"cassandra.nodetool_status","title":"Cassandra node ring status","summary":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","description":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection to the local Cassandra node.","May fail if JMX auth is misconfigured.","Does not modify Cassandra data or cluster state."],"args":[{"name":"host","type":"string","required":false,"default":"127.0.0.1","description":"JMX host for nodetool.","validation":{"enum":["127.0.0.1","localhost"]}},{"name":"port","type":"integer","required":false,"default":7199,"description":"JMX port.","validation":{"allowed":[7199]}}],"examples":[{"title":"Check local Cassandra ring","args":{}}],"search_terms":["ring health","node down","cluster health"],"command":{"binary":"nodetool","argv":["-h","{{ args.host }}","-p","{{ args.port }}","status"]}},{"id":"cassandra.nodetool_statusautocompaction","title":"nodetool statusautocompaction [keyspace] [table]","summary":"Check whether automatic compaction is running — for the whole node, one keyspace, or one table. The read that catches a table left with autocompaction off after a bulk load.","description":"Check whether automatic compaction is running — for the whole node, one keyspace, or one table. The read that catches a table left with autocompaction off after a bulk load.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Keyspace to check; empty checks the whole node.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"table","type":"string","required":false,"default":"","description":"Table to check; needs keyspace, and empty checks every table in it.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Node-wide","args":{}},{"title":"One table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["statusautocompaction","{{ args.keyspace? }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_stop_compaction","title":"nodetool stop <operation>","summary":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","description":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","kind":"exec","risk":"high","side_effects":["In-flight ops of the named type are aborted.","SSTables in progress are abandoned (no partial result)."],"args":[{"name":"operation","type":"string","required":true,"description":"Operation type.","validation":{"enum":["COMPACTION","VALIDATION","CLEANUP","SCRUB","VERIFY","INDEX_BUILD","VIEW_BUILD","ANTICOMPACTION"]}}],"examples":[{"title":"Stop all compactions","args":{"operation":"COMPACTION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["stop","{{ args.operation }}"]}},{"id":"cassandra.nodetool_tablehistograms","title":"nodetool tablehistograms <ks> <table>","summary":"Show local-node read/write/sstable/partition-size histograms for one table.","description":"Show local-node read/write/sstable/partition-size histograms for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":["p99 latency","wide partitions"],"command":{"binary":"nodetool","argv":["tablehistograms","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_tablestats","title":"Cassandra table stats","summary":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","description":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Output can be large for clusters with many tables."],"args":[{"name":"keyspace","type":"string","required":false,"description":"Optional keyspace to scope to (omit for all keyspaces).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Inspect a single keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":["sstable count","tombstones","space used per table"],"command":{"binary":"nodetool","argv":["tablestats","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_toppartitions","title":"nodetool toppartitions <keyspace> <table> <duration>","summary":"Sample one table's traffic for a few seconds and print its busiest partitions by read and write frequency — the direct answer to \"which key is hot\" that cassandra.cqlsh_largest_partitions cannot give, since the biggest partition and the busiest one are rarely the same.","description":"Sample one table's traffic for a few seconds and print its busiest partitions by read and write frequency — the direct answer to \"which key is hot\" that cassandra.cqlsh_largest_partitions cannot give, since the biggest partition and the busiest one are rarely the same.","kind":"exec","risk":"medium","side_effects":["Turns on request sampling for the named table for the duration, then reports and stops.","Sampling adds bookkeeping to every read and write on that table while it runs.","Blocks for the whole sampling duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to sample.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"duration_ms","type":"integer","required":false,"default":5000,"description":"How long to sample, in milliseconds.","validation":{"min":1000,"max":60000}},{"name":"top_count","type":"integer","required":false,"default":10,"description":"How many partitions to list per sampler.","validation":{"min":1,"max":100}}],"examples":[{"title":"Busiest partitions over five seconds","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["toppartitions","-k","{{ args.top_count }}","--","{{ args.keyspace }}","{{ args.table }}","{{ args.duration_ms }}"]}},{"id":"cassandra.nodetool_tpstats","title":"Cassandra thread pool stats","summary":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","description":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect thread pool pressure","args":{}}],"search_terms":["dropped mutations","dropped messages"],"command":{"binary":"nodetool","argv":["tpstats"]}},{"id":"cassandra.nodetool_truncatehints","title":"nodetool truncatehints [endpoint]","summary":"Delete the hints this node is holding — all of them, or only those for one endpoint. The release valve when a hint backlog is filling the disk or targets a node that will never come back. The deleted writes are gone from this node's hint store, so the peers they were for need a repair.","description":"Delete the hints this node is holding — all of them, or only those for one endpoint. The release valve when a hint backlog is filling the disk or targets a node that will never come back. The deleted writes are gone from this node's hint store, so the peers they were for need a repair.","kind":"exec","risk":"high","side_effects":["Pending hints are deleted; the writes they carried are not delivered.","Every peer whose hints were dropped is left inconsistent until a repair runs.","Frees the disk the hint files were using."],"args":[{"name":"endpoint","type":"string","required":false,"default":"","description":"IP address or hostname whose hints to delete; empty deletes every pending hint on this node.","validation":{"pattern":"^([A-Za-z0-9._:-]{1,255})?$","max_length":255}}],"examples":[{"title":"Drop hints for one dead peer","args":{"endpoint":"10.1.4.7"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["truncatehints","--","{{ args.endpoint? }}"]}},{"id":"cassandra.nodetool_upgradesstables","title":"nodetool upgradesstables <keyspace> [table]","summary":"Rewrite SSTables that are still in an older on-disk format into the current one — the step after a major-version upgrade, and what lets the old format's read path be retired.","description":"Rewrite SSTables that are still in an older on-disk format into the current one — the step after a major-version upgrade, and what lets the old format's read path be retired.","kind":"exec","risk":"high","side_effects":["Rewrites every out-of-date SSTable of the named tables — sustained disk and CPU, and hours on a large node.","Needs free disk space for the rewritten files while it runs.","Does nothing when every file is already current, unless include_all is set."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to upgrade.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to upgrade; empty upgrades every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"include_all","type":"boolean","required":false,"default":false,"description":"Rewrite every SSTable, including files already in the current format."}],"examples":[{"title":"Upgrade one table's SSTables","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\n[ \"$INCLUDE_ALL\" = \"true\" ] && flags=\"-a\"\nset -- \"$KEYSPACE\"\n[ -n \"$TABLE\" ] && set -- \"$@\" \"$TABLE\"\nexec nodetool upgradesstables $flags -- \"$@\"\n"]}},{"id":"cassandra.nodetool_verify","title":"nodetool verify [ks] [table]","summary":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","description":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","kind":"exec","risk":"medium","side_effects":["Reads every SSTable for the targeted scope.","IO-heavy; CPU light."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Verify one ks","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool verify \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool verify \"$2\"; else nodetool verify; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_version","title":"nodetool version","summary":"Show the Cassandra version string for the node.","description":"Show the Cassandra version string for the node.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["version"]}},{"id":"cassandra.nodetool_viewbuildstatus","title":"nodetool viewbuildstatus <keyspace> <view>","summary":"Show whether a materialized view has finished building, per node. Exits non-zero while the build is still running, and names the nodes that are behind.","description":"Show whether a materialized view has finished building, per node. Exits non-zero while the build is still running, and names the nodes that are behind.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the view.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"view","type":"string","required":true,"description":"Materialized view name.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"View build progress","args":{"keyspace":"valorant_ks","view":"matches_by_player"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["viewbuildstatus","--","{{ args.keyspace }}","{{ args.view }}"]}}]},{"version":"0.6.0","content_hash":"sha256:aae0974c5ddb85a0dede90c38c3c16ed590cb04400c212ce7e82548540a1007a","tarball_url":"https://registry.emisar.dev/v1/packs/cassandra/0.6.0/aae0974c5ddb85a0dede90c38c3c16ed590cb04400c212ce7e82548540a1007a/pack.tar.gz","actions":[{"id":"cassandra.analyze_disk_pressure","title":"Analyze Cassandra disk pressure","summary":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","description":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","kind":"script","risk":"low","side_effects":["Reads filesystem metadata (df, du counts).","Does not modify Cassandra data or configuration.","May create temporary files inside the runner's work directory."],"args":[{"name":"keyspace_filter","type":"string","required":false,"default":"","description":"Optional keyspace name to focus the analysis on.","validation":{"pattern":"^[a-zA-Z0-9_.*-]{0,80}$"}}],"examples":[{"title":"Analyze without keyspace filter","args":{}}],"search_terms":["disk full","running out of space"]},{"id":"cassandra.cqlsh_describe_keyspace","title":"cqlsh -e \"DESCRIBE KEYSPACE <ks>\"","summary":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","description":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace DDL","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACE '\"$1\"';' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_describe_schema","title":"cqlsh -e \"DESCRIBE SCHEMA\"","summary":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","description":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Full schema","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE SCHEMA;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_describe_table","title":"cqlsh -e \"DESCRIBE TABLE <ks>.<table>\"","summary":"Show the full DDL for one table — columns, primary key, and every table property (compaction, compression, gc_grace_seconds, caching, TTL defaults).","description":"Show the full DDL for one table — columns, primary key, and every table property (compaction, compression, gc_grace_seconds, caching, TTL defaults).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to describe.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table's DDL","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"DESCRIBE TABLE $1.$2;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.cqlsh_largest_partitions","title":"cqlsh -e \"SELECT * FROM system_views.max_partition_size\"","summary":"List each table's largest partition on this node, in mebibytes — the read that finds the wide partition behind slow reads, timeouts, or heap pressure.","description":"List each table's largest partition on this node, in mebibytes — the read that finds the wide partition behind slow reads, timeouts, or heap pressure.","kind":"exec","risk":"low","side_effects":["One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Largest partition per table","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, table_name, mebibytes FROM system_views.max_partition_size LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_list_keyspaces","title":"cqlsh -e \"DESCRIBE KEYSPACES\"","summary":"List all keyspaces.","description":"List all keyspaces.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Keyspaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_permissions","title":"cqlsh -e \"LIST ALL PERMISSIONS\"","summary":"List every permission granted to every role — who may read, write, or alter which keyspace and table. Needs CassandraAuthorizer and a login with permission to see other roles' grants.","description":"List every permission granted to every role — who may read, write, or alter which keyspace and table. Needs CassandraAuthorizer and a login with permission to see other roles' grants.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"All grants","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e 'LIST ALL PERMISSIONS;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_roles","title":"cqlsh -e \"LIST ROLES\"","summary":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","description":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Roles","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'LIST ROLES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_tables","title":"cqlsh -e \"SELECT table_name FROM system_schema.tables\"","summary":"List the tables in one keyspace by name — the cheap look-up before cassandra.cqlsh_describe_table, without the full DDL that cassandra.cqlsh_describe_keyspace dumps.","description":"List the tables in one keyspace by name — the cheap look-up before cassandra.cqlsh_describe_table, without the full DDL that cassandra.cqlsh_describe_keyspace dumps.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to list.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Tables in a keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT table_name FROM system_schema.tables WHERE keyspace_name = '$1';\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_repair_history","title":"cqlsh -e \"SELECT * FROM system_distributed.repair_history\"","summary":"List recent repair sessions the cluster recorded — keyspace, table, coordinator, start and finish time, and status. Shows what repaired and what failed, which cassandra.nodetool_repair's own output does not survive.","description":"List recent repair sessions the cluster recorded — keyspace, table, coordinator, start and finish time, and status. Shows what repaired and what failed, which cassandra.nodetool_repair's own output does not survive.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only.","A range scan of a cluster-wide table, bounded by the row limit."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Sessions to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent repair sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, columnfamily_name, coordinator, started_at, finished_at, status FROM system_distributed.repair_history LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_running_queries","title":"cqlsh -e \"SELECT * FROM system_views.queries\"","summary":"List the queries this node is executing right now, with how long each has been queued and running — the first look when a node is busy and nobody knows what it is doing. The query text includes literal values, so this returns application data and is approval-gated.","description":"List the queries this node is executing right now, with how long each has been queued and running — the first look when a node is busy and nobody knows what it is doing. The query text includes literal values, so this returns application data and is approval-gated.","kind":"exec","risk":"high","side_effects":["Query text includes the literals callers passed, so application data reaches the caller and the audit trail.","One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Queries to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"What this node is running now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT thread_id, queued_micros, running_micros, task FROM system_views.queries LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_select_by_key","title":"cqlsh -e \"SELECT * FROM <ks>.<table> WHERE <key> = <value>\"","summary":"Read the rows of one partition by its key — the \"does this row exist, and what does it hold\" lookup. Returns stored application data, so it is approval-gated. Use cassandra.nodetool_getendpoints for which replicas own the key without reading it.","description":"Read the rows of one partition by its key — the \"does this row exist, and what does it hold\" lookup. Returns stored application data, so it is approval-gated. Use cassandra.nodetool_getendpoints for which replicas own the key without reading it.","kind":"exec","risk":"high","side_effects":["Returns application data — whatever the partition holds reaches the caller and the audit trail.","A single-partition read on the coordinator, bounded by the row limit and the output cap.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key_column","type":"string","required":true,"description":"Partition key column to match.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key_value","type":"string","required":true,"description":"Key value, unquoted; the action quotes it according to key_type.","validation":{"pattern":"^[A-Za-z0-9._:+@-]{1,128}$","max_length":128}},{"name":"key_type","type":"string","required":false,"default":"text","description":"How to render the value in CQL — text quotes it, number and uuid pass it through bare.","validation":{"enum":["text","number","uuid"]}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Rows to return from the partition.","validation":{"min":1,"max":100}}],"examples":[{"title":"One partition by a text key","args":{"key_column":"match_id","key_value":"a41f2c7e","keyspace":"valorant_ks","table":"matches"}},{"title":"One partition by an integer key","args":{"key_column":"id","key_type":"number","key_value":"42","keyspace":"valorant_ks","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$KEY_TYPE\" in\n  text) predicate=\"$KEY_COLUMN = '$KEY_VALUE'\" ;;\n  number|uuid) predicate=\"$KEY_COLUMN = $KEY_VALUE\" ;;\n  *) printf 'unsupported key_type: %s\\n' \"$KEY_TYPE\" >&2; exit 2 ;;\nesac\nexec cqlsh -e \"SELECT * FROM $KEYSPACE.$TABLE WHERE $predicate LIMIT $LIMIT;\" \\\n  \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"\n"]}},{"id":"cassandra.cqlsh_select_rows","title":"cqlsh -e \"SELECT * FROM <ks>.<table> LIMIT <n>\"","summary":"Read a bounded sample of rows from one table. Returns stored application data, so it is approval-gated; use cassandra.cqlsh_select_by_key when you know the partition key, and cassandra.cqlsh_describe_table when you only need the shape.","description":"Read a bounded sample of rows from one table. Returns stored application data, so it is approval-gated; use cassandra.cqlsh_select_by_key when you know the partition key, and cassandra.cqlsh_describe_table when you only need the shape.","kind":"exec","risk":"high","side_effects":["Returns application data — whatever the table holds reaches the caller and the audit trail.","A range scan over the ring, bounded by the row limit and the output cap.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"limit","type":"integer","required":false,"default":10,"description":"Rows to return.","validation":{"min":1,"max":100}}],"examples":[{"title":"Ten rows from a table","args":{"keyspace":"valorant_ks","limit":10,"table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT * FROM $1.$2 LIMIT $3;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}","{{ args.table }}","{{ args.limit }}"]}},{"id":"cassandra.cqlsh_settings","title":"cqlsh -e \"SELECT name, value FROM system_views.settings\"","summary":"Show the configuration this node is actually running, from the system_views.settings virtual table — cassandra.yaml as parsed at boot plus every runtime change made since. Pass a filter to narrow it to one area (compaction, stream, hinted_handoff); the unfiltered dump is over 500 rows.","description":"Show the configuration this node is actually running, from the system_views.settings virtual table — cassandra.yaml as parsed at boot plus every runtime change made since. Pass a filter to narrow it to one area (compaction, stream, hinted_handoff); the unfiltered dump is over 500 rows.","kind":"exec","risk":"medium","side_effects":["One CQL query against a virtual table; nothing is read from disk.","Read-only.","Cassandra 5.0 masks credential settings itself; on 4.x it returns keystore and truststore passwords in the clear, so this action redacts them on the way out."],"args":[{"name":"filter","type":"string","required":false,"default":"","description":"Case-insensitive substring of the setting name; empty returns every setting.","validation":{"pattern":"^[A-Za-z0-9_.]{0,64}$","max_length":64}}],"examples":[{"title":"Every runtime setting","args":{}},{"title":"Just the streaming settings","args":{"filter":"stream"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","settings=$(cqlsh -e 'SELECT name, value FROM system_views.settings;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\") || exit $?\n[ -z \"$FILTER\" ] && { printf '%s\\n' \"$settings\"; exit 0; }\nprintf '%s\\n' \"$settings\" | grep -F -i -e \"$FILTER\"\nmatched=$?\n[ \"$matched\" -eq 1 ] && { printf 'no setting name matched: %s\\n' \"$FILTER\"; exit 0; }\nexit \"$matched\"\n"]}},{"id":"cassandra.cqlsh_system_peers","title":"SELECT * FROM system.peers_v2","summary":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","description":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Peers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers_v2;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\" || cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_system_size_estimates","title":"SELECT * FROM system.size_estimates","summary":"Show per-table partition + size estimates from the gossiped size_estimates table.","description":"Show per-table partition + size estimates from the gossiped size_estimates table.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Size estimates","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT keyspace_name, table_name, range_start, range_end, mean_partition_size, partitions_count FROM system.size_estimates LIMIT 200;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_tombstones_per_read","title":"cqlsh -e \"SELECT * FROM system_views.tombstones_per_read\"","summary":"Show how many tombstones each table scans per read on this node (count, max, p50, p99) — the read that confirms a delete-heavy or TTL-heavy table is the reason queries are slow or failing.","description":"Show how many tombstones each table scans per read on this node (count, max, p50, p99) — the read that confirms a delete-heavy or TTL-heavy table is the reason queries are slow or failing.","kind":"exec","risk":"low","side_effects":["One CQL query against a virtual table.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Tombstones scanned per read","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec cqlsh -e \"SELECT keyspace_name, table_name, count, max, p50th, p99th FROM system_views.tombstones_per_read LIMIT $1;\" \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.limit }}"]}},{"id":"cassandra.nodetool_assassinate","title":"nodetool assassinate <address>","summary":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","description":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","kind":"exec","risk":"critical","side_effects":["Node entry purged from gossip.","No data streaming — data that was on the node is gone.","Other replicas eventually catch up via repair."],"args":[{"name":"address","type":"string","required":true,"description":"IP address of the dead node.","validation":{"pattern":"^[0-9]{1,3}(\\.[0-9]{1,3}){3}$"}}],"examples":[{"title":"Remove permanently dead node","args":{"address":"10.0.0.42"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["assassinate","{{ args.address }}"]}},{"id":"cassandra.nodetool_bootstrap_resume","title":"nodetool bootstrap resume","summary":"Resume a bootstrap that failed part way, streaming only the ranges this node is still missing — the recovery when a joining node lost a stream and stopped short of joining the ring. Fails on a node that already finished bootstrapping.","description":"Resume a bootstrap that failed part way, streaming only the ranges this node is still missing — the recovery when a joining node lost a stream and stopped short of joining the ring. Fails on a node that already finished bootstrapping.","kind":"exec","risk":"high","side_effects":["Restarts streaming from the source replicas; expect sustained network and disk load until it completes.","Blocks until the bootstrap finishes or fails again.","The rate honours the caps set by cassandra.nodetool_setstreamthroughput and cassandra.nodetool_setinterdcstreamthroughput."],"args":[],"examples":[{"title":"Finish an interrupted bootstrap","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["bootstrap","resume"]}},{"id":"cassandra.nodetool_cleanup","title":"nodetool cleanup [ks]","summary":"Remove data no longer owned by this node (after a topology change). IO-heavy.","description":"Remove data no longer owned by this node (after a topology change). IO-heavy.","kind":"exec","risk":"high","side_effects":["SSTables rewritten without data that moved off this node.","Heavy IO + CPU; may take hours on large tables.","Free space requirement during cleanup."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Cleanup post-bootstrap","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool cleanup \"$1\"; else nodetool cleanup; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_clearsnapshot","title":"nodetool clearsnapshot -t <name>","summary":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","description":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","kind":"exec","risk":"high","side_effects":["Snapshot hard links removed.","Disk space reclaims as the underlying SSTables become orphaned."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag to delete.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Delete tag","args":{"tag":"old-backup"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clearsnapshot","-t","{{ args.tag }}"]}},{"id":"cassandra.nodetool_clientstats","title":"nodetool clientstats","summary":"List the clients connected to this node — count per user, driver, and protocol version. The read before cutting a node out of service, and the one that finds an old driver still talking to it.","description":"List the clients connected to this node — count per user, driver, and protocol version. The read before cutting a node out of service, and the one that finds an old driver still talking to it.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Connected clients","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clientstats"]}},{"id":"cassandra.nodetool_compact","title":"nodetool compact <ks> [table]","summary":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","description":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","kind":"exec","risk":"high","side_effects":["Heavy disk + CPU for the duration.","For STCS, creates one giant SSTable that is hard to compact later.","For LCS, may be fine."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Major-compact one table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool compact \"$2\" \"$1\"; else nodetool compact \"$2\"; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_compactionhistory","title":"nodetool compactionhistory","summary":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","description":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Recent compactions","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["compactionhistory"]}},{"id":"cassandra.nodetool_compactionstats","title":"Cassandra compaction statistics","summary":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","description":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect compaction backlog","args":{}}],"search_terms":["compactions backed up","compaction backlog","pending compactions"],"command":{"binary":"nodetool","argv":["compactionstats"]}},{"id":"cassandra.nodetool_datapaths","title":"nodetool datapaths","summary":"List the directories each table stores data in — the read that shows which disk a table actually lives on before you judge a full filesystem or a JBOD imbalance.","description":"List the directories each table stores data in — the read that shows which disk a table actually lives on before you judge a full filesystem or a JBOD imbalance.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Data directories per table","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["datapaths"]}},{"id":"cassandra.nodetool_decommission","title":"nodetool decommission","summary":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","description":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","kind":"exec","risk":"critical","side_effects":["All data streams to remaining replicas.","Heavy network + disk on this and peer nodes.","Node leaves the ring; tokens are reassigned.","Can take many hours on big datasets."],"args":[],"examples":[{"title":"Remove this node","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["decommission"]}},{"id":"cassandra.nodetool_describecluster","title":"nodetool describecluster","summary":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","description":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Cluster summary","args":{}}],"search_terms":["schema disagreement","schema mismatch"],"command":{"binary":"nodetool","argv":["describecluster"]}},{"id":"cassandra.nodetool_describering","title":"nodetool describering <keyspace>","summary":"Show token range → replica endpoint mapping for one keyspace.","description":"Show token range → replica endpoint mapping for one keyspace.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace's ring","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["describering","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_disableautocompaction","title":"nodetool disableautocompaction <keyspace> [table]","summary":"Stop automatic compaction for a keyspace or one table on this node — the usual move before a bulk load or a heavy backfill. Re-enable it with cassandra.nodetool_enableautocompaction as soon as the load is done.","description":"Stop automatic compaction for a keyspace or one table on this node — the usual move before a bulk load or a heavy backfill. Re-enable it with cassandra.nodetool_enableautocompaction as soon as the load is done.","kind":"exec","risk":"medium","side_effects":["New compactions stop being scheduled; compactions already running finish.","SSTable count and read latency grow for as long as it stays off, and disk use grows with them.","Runtime-only — a restart returns the node to automatic compaction."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to pause.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to pause; empty pauses every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Pause compaction on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disableautocompaction","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_disablebackup","title":"nodetool disablebackup","summary":"Stop incremental backup on this node — Cassandra stops hard-linking each new SSTable into the backups directory. Use when those links are filling the disk and the backup tooling is not clearing them.","description":"Stop incremental backup on this node — Cassandra stops hard-linking each new SSTable into the backups directory. Use when those links are filling the disk and the backup tooling is not clearing them.","kind":"exec","risk":"medium","side_effects":["New SSTables are no longer linked for backup, so incremental backups stop covering fresh data.","Links already created stay on disk.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[],"examples":[{"title":"Stop incremental backup","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablebackup"]}},{"id":"cassandra.nodetool_disablebinary","title":"nodetool disablebinary","summary":"Stop the native transport on this node — every CQL client is disconnected and no new client can connect to it. Gossip, streaming, and repair keep running, so the node stays a replica and keeps taking writes from its peers. Use to take one node out of client rotation without draining it.","description":"Stop the native transport on this node — every CQL client is disconnected and no new client can connect to it. Gossip, streaming, and repair keep running, so the node stays a replica and keeps taking writes from its peers. Use to take one node out of client rotation without draining it.","kind":"exec","risk":"critical","side_effects":["Connected clients are dropped and must reconnect elsewhere; a driver without other reachable nodes fails outright.","Requests this node was coordinating are lost, and the rest of the cluster carries its client load.","Reverse it with cassandra.nodetool_enablebinary; a restart also brings the transport back."],"args":[],"examples":[{"title":"Take this node out of client rotation","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablebinary"]}},{"id":"cassandra.nodetool_disablegossip","title":"nodetool disablegossip","summary":"Stop gossip on this node. Every peer marks it Down and stops routing replica traffic to it, while it keeps serving whatever clients are still connected — the isolation move for a node that is poisoning cluster state, and the way to strand a node if used carelessly.","description":"Stop gossip on this node. Every peer marks it Down and stops routing replica traffic to it, while it keeps serving whatever clients are still connected — the isolation move for a node that is poisoning cluster state, and the way to strand a node if used carelessly.","kind":"exec","risk":"critical","side_effects":["The cluster treats this node as Down — reads and writes route to other replicas, and hints pile up for it.","The node keeps its own client connections, so it can serve stale data while isolated.","Reverse it with cassandra.nodetool_enablegossip; the node then needs a repair for what it missed."],"args":[],"examples":[{"title":"Isolate this node from the ring","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablegossip"]}},{"id":"cassandra.nodetool_disablehandoff","title":"nodetool disablehandoff","summary":"Stop this node storing hints for unreachable peers. Different from cassandra.nodetool_pausehandoff, which keeps storing them and only stops delivery. Use when hint disk use is the problem, not delivery load.","description":"Stop this node storing hints for unreachable peers. Different from cassandra.nodetool_pausehandoff, which keeps storing them and only stops delivery. Use when hint disk use is the problem, not delivery load.","kind":"exec","risk":"medium","side_effects":["Writes destined for a down peer are no longer saved, so recovering that peer needs a repair.","Existing hints stay on disk and still replay.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[],"examples":[{"title":"Stop storing hints","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablehandoff"]}},{"id":"cassandra.nodetool_disablehintsfordc","title":"nodetool disablehintsfordc <datacenter>","summary":"Stop this node storing hints for one datacenter — the move when a remote datacenter is down for maintenance, or is being retired, and its hints would otherwise pile up on every local node.","description":"Stop this node storing hints for one datacenter — the move when a remote datacenter is down for maintenance, or is being retired, and its hints would otherwise pile up on every local node.","kind":"exec","risk":"medium","side_effects":["Writes destined for that datacenter's replicas stop being saved, so bringing it back needs a repair.","Hints for other datacenters are unaffected.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"datacenter","type":"string","required":true,"description":"Datacenter name as the snitch reports it.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Stop hints for a retiring datacenter","args":{"datacenter":"gcp-us-east1"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["disablehintsfordc","--","{{ args.datacenter }}"]}},{"id":"cassandra.nodetool_drain","title":"nodetool drain","summary":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","description":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","kind":"exec","risk":"critical","side_effects":["Node stops accepting writes immediately.","All memtables flushed.","Native + Thrift transports closed.","Only restart restores the node."],"args":[],"examples":[{"title":"Drain before restart","args":{}}],"search_terms":["safe shutdown","flush before restart"],"command":{"binary":"nodetool","argv":["drain"]}},{"id":"cassandra.nodetool_enableautocompaction","title":"nodetool enableautocompaction <keyspace> [table]","summary":"Resume automatic compaction for a keyspace or one table on this node after a cassandra.nodetool_disableautocompaction. Confirm with cassandra.nodetool_statusautocompaction.","description":"Resume automatic compaction for a keyspace or one table on this node after a cassandra.nodetool_disableautocompaction. Confirm with cassandra.nodetool_statusautocompaction.","kind":"exec","risk":"medium","side_effects":["Compaction resumes immediately and works off whatever backlog accumulated, which is CPU and disk heavy on a large one.","The backlog respects the cap set by cassandra.nodetool_setcompactionthroughput."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to resume.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to resume; empty resumes every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Resume compaction on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enableautocompaction","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_enablebackup","title":"nodetool enablebackup","summary":"Start incremental backup on this node — every new SSTable is hard-linked into the table's backups directory for an external backup job to collect. Confirm with cassandra.nodetool_service_status.","description":"Start incremental backup on this node — every new SSTable is hard-linked into the table's backups directory for an external backup job to collect. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Each new SSTable gains a hard link that only an external job removes, so disk use grows until something clears them.","Covers SSTables written from now on, not existing data; that needs cassandra.nodetool_snapshot."],"args":[],"examples":[{"title":"Start incremental backup","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablebackup"]}},{"id":"cassandra.nodetool_enablebinary","title":"nodetool enablebinary","summary":"Start the native transport on this node so CQL clients can connect again — the recovery from cassandra.nodetool_disablebinary. Confirm with cassandra.nodetool_service_status.","description":"Start the native transport on this node so CQL clients can connect again — the recovery from cassandra.nodetool_disablebinary. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"critical","side_effects":["Clients start connecting immediately, so a node that is not ready to serve reads takes traffic at once.","Check the node is Up/Normal with cassandra.nodetool_status first."],"args":[],"examples":[{"title":"Return this node to client rotation","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablebinary"]}},{"id":"cassandra.nodetool_enablegossip","title":"nodetool enablegossip","summary":"Start gossip on this node so the cluster sees it as Up again — the recovery from cassandra.nodetool_disablegossip. Confirm with cassandra.nodetool_service_status and cassandra.nodetool_status.","description":"Start gossip on this node so the cluster sees it as Up again — the recovery from cassandra.nodetool_disablegossip. Confirm with cassandra.nodetool_service_status and cassandra.nodetool_status.","kind":"exec","risk":"critical","side_effects":["Peers mark the node Up and resume routing replica traffic to it at once.","Writes it missed arrive as hints only inside the hint window; anything older needs a repair."],"args":[],"examples":[{"title":"Rejoin the ring","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablegossip"]}},{"id":"cassandra.nodetool_enablehandoff","title":"nodetool enablehandoff","summary":"Resume storing hints for unreachable peers after a cassandra.nodetool_disablehandoff. Confirm with cassandra.nodetool_service_status.","description":"Resume storing hints for unreachable peers after a cassandra.nodetool_disablehandoff. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Writes for a down peer are saved again, using disk for as long as the window set by cassandra.nodetool_setmaxhintwindow.","Nothing recovers the hints missed while storing was off; that gap needs a repair."],"args":[],"examples":[{"title":"Store hints again","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablehandoff"]}},{"id":"cassandra.nodetool_enablehintsfordc","title":"nodetool enablehintsfordc <datacenter>","summary":"Resume storing hints for one datacenter after a cassandra.nodetool_disablehintsfordc — the step that goes with bringing a remote datacenter back into service.","description":"Resume storing hints for one datacenter after a cassandra.nodetool_disablehintsfordc — the step that goes with bringing a remote datacenter back into service.","kind":"exec","risk":"medium","side_effects":["Writes for that datacenter's replicas are saved again while they are unreachable.","Nothing recovers the hints missed while it was off; that gap needs a repair."],"args":[{"name":"datacenter","type":"string","required":true,"description":"Datacenter name as the snitch reports it.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Store hints for a datacenter again","args":{"datacenter":"va1"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["enablehintsfordc","--","{{ args.datacenter }}"]}},{"id":"cassandra.nodetool_failuredetector","title":"nodetool failuredetector","summary":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","description":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Phi scores","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["failuredetector"]}},{"id":"cassandra.nodetool_flush","title":"nodetool flush [ks] [table]","summary":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","description":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","kind":"exec","risk":"high","side_effects":["Memtables for the targeted scope are flushed to disk.","Brief IO spike.","Commit log may be marked clean for the affected segments."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table (requires keyspace).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Flush one keyspace","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool flush \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool flush \"$2\"; else nodetool flush; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_garbagecollect","title":"nodetool garbagecollect <keyspace> [table]","summary":"Rewrite a table's SSTables to drop data already deleted or expired, without waiting for compaction to reach it — the way to reclaim space from a tombstone-heavy table on one node. Slower and heavier than letting compaction do the work.","description":"Rewrite a table's SSTables to drop data already deleted or expired, without waiting for compaction to reach it — the way to reclaim space from a tombstone-heavy table on one node. Slower and heavier than letting compaction do the work.","kind":"exec","risk":"high","side_effects":["Rewrites every SSTable of the named tables on this node — sustained disk read, write, and CPU for the duration.","Needs free disk space for the rewritten files while it runs.","Data past gc_grace_seconds is purged; nothing recoverable is lost."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to collect.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to collect; empty collects every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"granularity","type":"string","required":false,"default":"ROW","description":"ROW drops deleted partitions and rows; CELL also drops overwritten and deleted cells, at more cost.","validation":{"enum":["ROW","CELL"]}}],"examples":[{"title":"Reclaim space on one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["garbagecollect","-g","{{ args.granularity }}","--","{{ args.keyspace }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_gcstats","title":"nodetool gcstats","summary":"Show garbage-collection statistics since the last call — pause counts, max and total elapsed time, and memory reclaimed. Long pauses here explain client timeouts that the latency histograms alone do not.","description":"Show garbage-collection statistics since the last call — pause counts, max and total elapsed time, and memory reclaimed. Long pauses here explain client timeouts that the latency histograms alone do not.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only.","Counters reset on read, so each call reports the interval since the previous one."],"args":[],"examples":[{"title":"GC since the last read","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gcstats"]}},{"id":"cassandra.nodetool_getbatchlogreplaythrottle","title":"nodetool getbatchlogreplaythrottle","summary":"Show the current batchlog replay throttle in KiB/s.","description":"Show the current batchlog replay throttle in KiB/s.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current batchlog replay throttle","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getbatchlogreplaythrottle"]}},{"id":"cassandra.nodetool_getcompactionthreshold","title":"nodetool getcompactionthreshold <keyspace> <table>","summary":"Show the min and max size-tiered compaction thresholds for one table.","description":"Show the min and max size-tiered compaction thresholds for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to read.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Thresholds for one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthreshold","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_getcompactionthroughput","title":"nodetool getcompactionthroughput","summary":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","description":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Compaction throughput","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthroughput"]}},{"id":"cassandra.nodetool_getconcurrency","title":"nodetool getconcurrency","summary":"List every request-processing stage on this node with its core and maximum pool size — the thread limits cassandra.nodetool_setconcurrency changes.","description":"List every request-processing stage on this node with its core and maximum pool size — the thread limits cassandra.nodetool_setconcurrency changes.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Stage thread limits","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrency"]}},{"id":"cassandra.nodetool_getconcurrentcompactors","title":"nodetool getconcurrentcompactors","summary":"Show the current concurrent_compactors setting.","description":"Show the current concurrent_compactors setting.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent compactors","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentcompactors"]}},{"id":"cassandra.nodetool_getconcurrentviewbuilders","title":"nodetool getconcurrentviewbuilders","summary":"Show how many materialized-view builds this node runs at once.","description":"Show how many materialized-view builds this node runs at once.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent view builders","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentviewbuilders"]}},{"id":"cassandra.nodetool_getendpoints","title":"nodetool getendpoints <ks> <table> <key>","summary":"Show which replicas own a specific partition key. Use to confirm read/write routing.","description":"Show which replicas own a specific partition key. Use to confirm read/write routing.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key (as a literal).","validation":{"pattern":"^[a-zA-Z0-9_:.][a-zA-Z0-9_\\-:.]{0,255}$"}}],"examples":[{"title":"Owning replicas","args":{"key":"user-1234","keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getendpoints","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getinterdcstreamthroughput","title":"nodetool getinterdcstreamthroughput","summary":"Show this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters. Reports \"unlimited\" when throttling is off.","description":"Show this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters. Reports \"unlimited\" when throttling is off.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to read, and in which unit. stream_megabits reports Mb/s, stream_mib the same cap in MiB/s, and entire_sstable_mib the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Cross-datacenter stream throughput in Mb/s","args":{}},{"title":"Cross-datacenter stream throughput in MiB/s","args":{"cap":"stream_mib"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"-d\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool getinterdcstreamthroughput \"$flag\"\n"]}},{"id":"cassandra.nodetool_getlogginglevels","title":"nodetool getlogginglevels","summary":"Show the current per-logger levels.","description":"Show the current per-logger levels.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Logger levels","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getlogginglevels"]}},{"id":"cassandra.nodetool_getmaxhintwindow","title":"nodetool getmaxhintwindow","summary":"Show how long this node keeps writing hints for an unreachable peer, in milliseconds.","description":"Show how long this node keeps writing hints for an unreachable peer, in milliseconds.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current hint window","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getmaxhintwindow"]}},{"id":"cassandra.nodetool_getseeds","title":"nodetool getseeds","summary":"List the seed nodes this node is currently using, excluding its own address — the running value, which drifts from cassandra.yaml after a cassandra.nodetool_reloadseeds or a seed-provider change.","description":"List the seed nodes this node is currently using, excluding its own address — the running value, which drifts from cassandra.yaml after a cassandra.nodetool_reloadseeds or a seed-provider change.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Seeds in use","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getseeds"]}},{"id":"cassandra.nodetool_getsnapshotthrottle","title":"nodetool getsnapshotthrottle","summary":"Show how many hard links per second snapshot and clearsnapshot may create. An unthrottled node reports the maximum long value rather than a word.","description":"Show how many hard links per second snapshot and clearsnapshot may create. An unthrottled node reports the maximum long value rather than a word.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current snapshot throttle","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getsnapshotthrottle"]}},{"id":"cassandra.nodetool_getsstables","title":"nodetool getsstables <keyspace> <table> <key>","summary":"List the SSTable files that hold one partition key — how many files a read of that key must touch. Empty output means the key's data is still in the memtable or absent.","description":"List the SSTable files that hold one partition key — how many files a read of that key must touch. Empty output means the key's data is still in the memtable or absent.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table holding the key.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key, in the string form nodetool accepts.","validation":{"pattern":"^[A-Za-z0-9._:+@-]{1,128}$","max_length":128}}],"examples":[{"title":"Files holding one key","args":{"key":"a41f2c7e","keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getsstables","--","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getstreamthroughput","title":"nodetool getstreamthroughput","summary":"Show this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Reports \"unlimited\" when throttling is off.","description":"Show this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Reports \"unlimited\" when throttling is off.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to read, and in which unit. stream_megabits reports Mb/s, stream_mib the same cap in MiB/s, and entire_sstable_mib the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Stream throughput in Mb/s","args":{}},{"title":"Stream throughput in MiB/s","args":{"cap":"stream_mib"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"-d\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool getstreamthroughput \"$flag\"\n"]}},{"id":"cassandra.nodetool_gettimeout","title":"nodetool gettimeout <type>","summary":"Show one of this node's request or internode timeouts, in milliseconds.","description":"Show one of this node's request or internode timeouts, in milliseconds.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"timeout_type","type":"string","required":true,"description":"Timeout to read.","validation":{"enum":["read","range","write","counterwrite","cascontention","truncate","internodeconnect","internodeuser","internodestreaminguser","misc"]}}],"examples":[{"title":"Current read timeout","args":{"timeout_type":"read"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gettimeout","{{ args.timeout_type }}"]}},{"id":"cassandra.nodetool_gettraceprobability","title":"nodetool gettraceprobability","summary":"Show the fraction of requests this node traces (0 = tracing off).","description":"Show the fraction of requests this node traces (0 = tracing off).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Current trace probability","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["gettraceprobability"]}},{"id":"cassandra.nodetool_gossipinfo","title":"nodetool gossipinfo","summary":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","description":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Gossip view","args":{}}],"search_terms":["node stuck joining"],"command":{"binary":"nodetool","argv":["gossipinfo"]}},{"id":"cassandra.nodetool_info","title":"nodetool info","summary":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","description":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"This node","args":{}}],"search_terms":["node uptime","heap usage"],"command":{"binary":"nodetool","argv":["info"]}},{"id":"cassandra.nodetool_invalidatecountercache","title":"nodetool invalidatecountercache","summary":"Drop the counter cache.","description":"Drop the counter cache.","kind":"exec","risk":"medium","side_effects":["Counter cache cleared.","Counter reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop counter cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecountercache"]}},{"id":"cassandra.nodetool_invalidatecredentialscache","title":"nodetool invalidatecredentialscache","summary":"Drop this node's cached credentials so a changed or revoked password takes effect now instead of when the cache expires. Needs PasswordAuthenticator.","description":"Drop this node's cached credentials so a changed or revoked password takes effect now instead of when the cache expires. Needs PasswordAuthenticator.","kind":"exec","risk":"medium","side_effects":["The next authentication for each role reads from the auth keyspace, so sign-ins are briefly slower.","Sessions already authenticated are not disconnected."],"args":[],"examples":[{"title":"Apply a password change now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecredentialscache"]}},{"id":"cassandra.nodetool_invalidatekeycache","title":"nodetool invalidatekeycache","summary":"Drop the key cache. Reads pay cold-cache cost until it warms.","description":"Drop the key cache. Reads pay cold-cache cost until it warms.","kind":"exec","risk":"medium","side_effects":["Key cache cleared.","Next reads must do bloom-filter + summary + index lookups."],"args":[],"examples":[{"title":"Drop key cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatekeycache"]}},{"id":"cassandra.nodetool_invalidatepermissionscache","title":"nodetool invalidatepermissionscache","summary":"Drop this node's cached permissions so a GRANT or REVOKE takes effect now instead of when the cache expires. Needs CassandraAuthorizer.","description":"Drop this node's cached permissions so a GRANT or REVOKE takes effect now instead of when the cache expires. Needs CassandraAuthorizer.","kind":"exec","risk":"medium","side_effects":["The next request per role and resource re-reads permissions, so queries are briefly slower.","Sessions already authorized keep running; only the next permission check is re-evaluated."],"args":[],"examples":[{"title":"Apply a REVOKE now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatepermissionscache"]}},{"id":"cassandra.nodetool_invalidaterolescache","title":"nodetool invalidaterolescache","summary":"Drop this node's cached roles so a role or membership change takes effect now instead of when the cache expires — the companion to cassandra.nodetool_invalidatepermissionscache after editing roles.","description":"Drop this node's cached roles so a role or membership change takes effect now instead of when the cache expires — the companion to cassandra.nodetool_invalidatepermissionscache after editing roles.","kind":"exec","risk":"medium","side_effects":["The next request per role re-reads the roles table, so queries are briefly slower.","Sessions already authenticated keep running under the reloaded role."],"args":[],"examples":[{"title":"Apply a role change now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterolescache"]}},{"id":"cassandra.nodetool_invalidaterowcache","title":"nodetool invalidaterowcache","summary":"Drop the row cache.","description":"Drop the row cache.","kind":"exec","risk":"medium","side_effects":["Row cache cleared.","Next reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop row cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterowcache"]}},{"id":"cassandra.nodetool_listpendinghints","title":"nodetool listpendinghints","summary":"List the hints this node is holding for peers that were unreachable — how much replay is waiting, and for whom. Reports plainly when there are none.","description":"List the hints this node is holding for peers that were unreachable — how much replay is waiting, and for whom. Reports plainly when there are none.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Hints waiting to replay","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listpendinghints"]}},{"id":"cassandra.nodetool_listsnapshots","title":"nodetool listsnapshots","summary":"List all snapshots on this node with size + creation timestamp.","description":"List all snapshots on this node with size + creation timestamp.","kind":"exec","risk":"low","side_effects":["Reads disk metadata.","Read-only."],"args":[],"examples":[{"title":"All snapshots","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listsnapshots"]}},{"id":"cassandra.nodetool_netstats","title":"nodetool netstats","summary":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","description":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Net stats","args":{}}],"search_terms":["streaming progress","streaming stuck","bootstrap progress"],"command":{"binary":"nodetool","argv":["netstats"]}},{"id":"cassandra.nodetool_pausehandoff","title":"nodetool pausehandoff","summary":"Pause hint delivery from this node. Hints keep accumulating; only the replay to peers stops — the move when a peer that just came back is being flooded. Resume with cassandra.nodetool_resumehandoff.","description":"Pause hint delivery from this node. Hints keep accumulating; only the replay to peers stops — the move when a peer that just came back is being flooded. Resume with cassandra.nodetool_resumehandoff.","kind":"exec","risk":"medium","side_effects":["Stored hints stop replaying; they stay on disk and grow.","Peers stay inconsistent until delivery resumes or a repair runs.","Runtime-only — a restart resumes delivery."],"args":[],"examples":[{"title":"Pause hint delivery","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["pausehandoff"]}},{"id":"cassandra.nodetool_proxyhistograms","title":"nodetool proxyhistograms","summary":"Show coordinator-side read/write latency histograms — what clients actually see.","description":"Show coordinator-side read/write latency histograms — what clients actually see.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Coordinator latencies","args":{}}],"search_terms":["p99 latency","latency percentiles","reads are slow","writes are slow"],"command":{"binary":"nodetool","argv":["proxyhistograms"]}},{"id":"cassandra.nodetool_rebuild","title":"nodetool rebuild [source_dc]","summary":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","description":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","kind":"exec","risk":"high","side_effects":["Heavy streaming workload.","Existing data on this node is NOT removed first.","Best run on a node that has empty data dirs."],"args":[{"name":"source_dc","type":"string","required":false,"default":"","description":"Source DC name (empty = any).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rebuild from us-east","args":{"source_dc":"us-east"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool rebuild \"$1\"; else nodetool rebuild; fi","emisar","{{ args.source_dc }}"]}},{"id":"cassandra.nodetool_rebuild_index","title":"nodetool rebuild_index <keyspace> <table> <index>","summary":"Rebuild one secondary index on this node from its base table — the fix when an index returns stale or missing rows after a restore, a scrub, or index corruption.","description":"Rebuild one secondary index on this node from its base table — the fix when an index returns stale or missing rows after a restore, a scrub, or index corruption.","kind":"exec","risk":"high","side_effects":["Reads the whole base table on this node and rewrites the index — sustained disk and CPU for the duration.","Queries using the index return incomplete results until the rebuild finishes."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Base table of the index.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"index","type":"string","required":true,"description":"Index name as the schema declares it.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Rebuild one index","args":{"index":"matches_player_idx","keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["rebuild_index","--","{{ args.keyspace }}","{{ args.table }}","{{ args.index }}"]}},{"id":"cassandra.nodetool_refresh","title":"nodetool refresh <keyspace> <table>","summary":"Load SSTable files that were placed into a table's data directory into the running node, with no restart — the last step of a file-level restore. Cassandra 5.0 prints a deprecation notice pointing at `nodetool import`, and still performs the load.","description":"Load SSTable files that were placed into a table's data directory into the running node, with no restart — the last step of a file-level restore. Cassandra 5.0 prints a deprecation notice pointing at `nodetool import`, and still performs the load.","kind":"exec","risk":"medium","side_effects":["The node starts serving whatever rows those files contain; a wrong file set changes query results.","Loading a large file set triggers compaction on the table."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table whose directory holds the new files.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Pick up restored SSTables","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["refresh","--","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_refreshsizeestimates","title":"nodetool refreshsizeestimates","summary":"Recompute the system.size_estimates table this node publishes. Run it when cassandra.cqlsh_system_size_estimates looks stale — Spark and analytics connectors split work from those numbers.","description":"Recompute the system.size_estimates table this node publishes. Run it when cassandra.cqlsh_system_size_estimates looks stale — Spark and analytics connectors split work from those numbers.","kind":"exec","risk":"medium","side_effects":["Rewrites this node's size_estimates rows; it reads SSTable metadata, not data.","Cheap on a small node, noticeable on one with many tables."],"args":[],"examples":[{"title":"Recompute size estimates","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["refreshsizeestimates"]}},{"id":"cassandra.nodetool_reloadlocalschema","title":"nodetool reloadlocalschema","summary":"Reload this node's schema from its own system tables — the first, cheap remedy when cassandra.nodetool_describecluster reports this node on a different schema version from the rest.","description":"Reload this node's schema from its own system tables — the first, cheap remedy when cassandra.nodetool_describecluster reports this node on a different schema version from the rest.","kind":"exec","risk":"medium","side_effects":["Rebuilds the in-memory schema from local system tables; it pulls nothing from peers and drops nothing.","Brief pause on schema-dependent work while it reloads."],"args":[],"examples":[{"title":"Reload the local schema","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadlocalschema"]}},{"id":"cassandra.nodetool_reloadseeds","title":"nodetool reloadseeds","summary":"Re-read the seed list from the seed provider without restarting — the step after editing seeds in cassandra.yaml, typically while replacing seed nodes. Read the result back with cassandra.nodetool_getseeds.","description":"Re-read the seed list from the seed provider without restarting — the step after editing seeds in cassandra.yaml, typically while replacing seed nodes. Read the result back with cassandra.nodetool_getseeds.","kind":"exec","risk":"medium","side_effects":["Replaces the in-memory seed list; gossip with current peers is unaffected.","Prints the new list, or says the provider returned no remote addresses."],"args":[],"examples":[{"title":"Re-read the seed list","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadseeds"]}},{"id":"cassandra.nodetool_reloadssl","title":"nodetool reloadssl","summary":"Reload the keystore and truststore from disk so a renewed certificate takes effect without a restart — the step that finishes a certificate rotation on a live node.","description":"Reload the keystore and truststore from disk so a renewed certificate takes effect without a restart — the step that finishes a certificate rotation on a live node.","kind":"exec","risk":"medium","side_effects":["New connections use the reloaded material; connections already established keep their current session.","A keystore that is unreadable or has the wrong password fails here, before it can break new connections."],"args":[],"examples":[{"title":"Pick up a renewed certificate","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["reloadssl"]}},{"id":"cassandra.nodetool_relocatesstables","title":"nodetool relocatesstables <keyspace> <table>","summary":"Move a table's SSTables onto the disk that owns their token range — the fix after adding or replacing a data directory on a node that spreads data across several disks. A no-op on a node with one data directory.","description":"Move a table's SSTables onto the disk that owns their token range — the fix after adding or replacing a data directory on a node that spreads data across several disks. A no-op on a node with one data directory.","kind":"exec","risk":"high","side_effects":["Rewrites SSTables onto their correct disk — sustained disk read and write for the duration.","Needs free space on the target disk while files are moved."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to relocate.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to relocate.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Rebalance one table across disks","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["relocatesstables","--","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_removenode","title":"nodetool removenode <host-id>","summary":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","description":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","kind":"exec","risk":"critical","side_effects":["Other replicas stream the dead node's data to their successors.","Heavy network + disk during stream.","Token range reassigned permanently."],"args":[{"name":"host_id","type":"string","required":true,"description":"Host ID UUID (from nodetool status).","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Remove a down node","args":{"host_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["remove dead node"],"command":{"binary":"nodetool","argv":["removenode","{{ args.host_id }}"]}},{"id":"cassandra.nodetool_repair","title":"Cassandra repair","summary":"Wrap `nodetool repair`.","description":"Wrap `nodetool repair`. The most dangerous \"normal\" operation — repair reconciles data between replicas, can take hours, produces significant cluster-wide load, may interact poorly with TTL/tombstone-heavy tables, and can worsen latency on every replica it touches. Always inspect ring status, compactions, disk, and logs first. Prefer mode=preview — a dry run that estimates the repair without performing it (requires Cassandra 4.0+) — before a real repair. Refuse to proceed if the ring has DN/UJ/UL/UM nodes.","kind":"exec","risk":"high","side_effects":["Repair coordinates with replicas across the cluster.","Generates significant network, CPU, and disk I/O.","Schedules anti-compaction and validation tasks.","Can run for minutes to hours depending on dataset size.","May worsen latency on the local node and on replica nodes for the duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to repair.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional single table to repair (empty = whole keyspace).","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"mode","type":"string","required":false,"default":"preview","description":"Repair mode.","validation":{"enum":["preview","full","incremental"]}},{"name":"primary_range","type":"boolean","required":false,"default":true,"description":"Restrict to the primary token range (recommended)."},{"name":"parallelism","type":"string","required":false,"default":"sequential","description":"Parallelism mode.","validation":{"enum":["sequential","parallel","dc_parallel"]}}],"examples":[{"title":"Dry-run repair preview on one keyspace","args":{"keyspace":"valorant_ks","mode":"preview"}}],"search_terms":["anti-entropy","inconsistent replicas","data consistency"],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\ncase \"$MODE\" in\n  preview) flags=\"--preview\" ;;\n  full) flags=\"-full\" ;;\n  # Incremental is nodetool's own default on 4.x and 5.x and has no flag\n  # of its own (-inc went away after 3.x). Named anyway: falling through\n  # meant the operator asked for incremental and silently got whatever\n  # this node's version defaults to, and the next enum value added here\n  # would have inherited the same silence.\n  incremental) flags=\"\" ;;\n  *) printf 'unsupported repair mode: %s\\n' \"$MODE\" >&2; exit 2 ;;\nesac\n[ \"$PR\" = \"true\" ] && flags=\"$flags -pr\"\ncase \"$PAR\" in\n  sequential) flags=\"$flags -seq\" ;;\n  dc_parallel) flags=\"$flags -dcpar\" ;;\nesac\nset -- \"$KS\"\n[ -n \"$TBL\" ] && set -- \"$@\" \"$TBL\"\nexec nodetool repair $flags \"$@\"\n"]}},{"id":"cassandra.nodetool_repair_admin_list","title":"nodetool repair_admin list","summary":"List the incremental repair sessions this node knows about. A session stuck in a non-finished state is what keeps SSTables pending repair and blocks later repairs; \"no sessions\" is the healthy answer.","description":"List the incremental repair sessions this node knows about. A session stuck in a non-finished state is what keeps SSTables pending repair and blocks later repairs; \"no sessions\" is the healthy answer.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"include_completed","type":"boolean","required":false,"default":false,"description":"Include finished sessions as well as the ones still in flight."}],"examples":[{"title":"Sessions still in flight","args":{}},{"title":"Every recorded session","args":{"include_completed":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ \"$ALL\" = \"true\" ] && exec nodetool repair_admin list --all\nexec nodetool repair_admin list\n"]}},{"id":"cassandra.nodetool_replaybatchlog","title":"nodetool replaybatchlog","summary":"Replay this node's batchlog now and wait for it to finish, instead of waiting for the periodic sweep — the step that clears batches left behind after a node came back from an outage.","description":"Replay this node's batchlog now and wait for it to finish, instead of waiting for the periodic sweep — the step that clears batches left behind after a node came back from an outage.","kind":"exec","risk":"medium","side_effects":["Replays batched writes to their replicas, adding write load until the backlog clears.","Blocks until the replay finishes.","The rate honours the cap set by cassandra.nodetool_setbatchlogreplaythrottle."],"args":[],"examples":[{"title":"Clear the batchlog now","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["replaybatchlog"]}},{"id":"cassandra.nodetool_resumehandoff","title":"nodetool resumehandoff","summary":"Resume hint delivery from this node after a cassandra.nodetool_pausehandoff. Confirm with cassandra.nodetool_service_status.","description":"Resume hint delivery from this node after a cassandra.nodetool_pausehandoff. Confirm with cassandra.nodetool_service_status.","kind":"exec","risk":"medium","side_effects":["Stored hints start replaying to their peers immediately.","A large backlog puts load on this node and on the peers receiving it; cap it with cassandra.nodetool_sethintedhandoffthrottlekb."],"args":[],"examples":[{"title":"Resume hint delivery","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["resumehandoff"]}},{"id":"cassandra.nodetool_ring","title":"nodetool ring [keyspace]","summary":"Show the token ring with owner host per token.","description":"Show the token ring with owner host per token.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (default — all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Ring","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool ring \"$1\"; else nodetool ring; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_scrub","title":"nodetool scrub <keyspace> [table]","summary":"Rebuild a table's SSTables on this node, validating each row as it goes — the repair for corrupt files reported in the log. Snapshots first by default, so the pre-scrub files remain until you clear that snapshot.","description":"Rebuild a table's SSTables on this node, validating each row as it goes — the repair for corrupt files reported in the log. Snapshots first by default, so the pre-scrub files remain until you clear that snapshot.","kind":"exec","risk":"high","side_effects":["Rewrites every SSTable of the named tables — sustained disk and CPU for the duration.","Takes a snapshot first, which occupies disk until cassandra.nodetool_clearsnapshot removes it.","With skip_corrupted, unreadable rows are dropped instead of failing the scrub; that data is gone from this node and needs a repair."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to scrub.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to scrub; empty scrubs every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"skip_corrupted","type":"boolean","required":false,"default":false,"description":"Drop rows that cannot be read instead of stopping at them."}],"examples":[{"title":"Scrub one table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\n[ \"$SKIP_CORRUPTED\" = \"true\" ] && flags=\"-s\"\nset -- \"$KEYSPACE\"\n[ -n \"$TABLE\" ] && set -- \"$@\" \"$TABLE\"\nexec nodetool scrub $flags -- \"$@\"\n"]}},{"id":"cassandra.nodetool_service_status","title":"nodetool statusbinary / statusgossip / statusbackup / statushandoff","summary":"Check what this node currently has switched on — native transport (client traffic), gossip, incremental backup, and hinted handoff — in one call. The read to take before and after any of the enable/disable actions.","description":"Check what this node currently has switched on — native transport (client traffic), gossip, incremental backup, and hinted handoff — in one call. The read to take before and after any of the enable/disable actions.","kind":"exec","risk":"low","side_effects":["Four JMX calls.","Read-only."],"args":[],"examples":[{"title":"What is switched on","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","for check in statusbinary statusgossip statusbackup statushandoff; do\n  printf '%s: ' \"$check\"\n  nodetool \"$check\" || exit $?\ndone\n"]}},{"id":"cassandra.nodetool_setbatchlogreplaythrottle","title":"nodetool setbatchlogreplaythrottle <KiB/s>","summary":"Set the batchlog replay throttle in KiB/s. Lower it when replaying batches after an outage is adding load to an already busy node; 0 disables throttling. Read the current value with cassandra.nodetool_getbatchlogreplaythrottle.","description":"Set the batchlog replay throttle in KiB/s. Lower it when replaying batches after an outage is adding load to an already busy node; 0 disables throttling. Read the current value with cassandra.nodetool_getbatchlogreplaythrottle.","kind":"exec","risk":"medium","side_effects":["Applies to replay work that starts after the change.","Cassandra reduces the rate proportionally to the number of nodes in the cluster.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"kb_per_sec","type":"integer","required":true,"description":"Throttle in KiB/s; 0 disables throttling.","validation":{"min":0,"max":1048576}}],"examples":[{"title":"Halve the default replay rate","args":{"kb_per_sec":512}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setbatchlogreplaythrottle","{{ args.kb_per_sec }}"]}},{"id":"cassandra.nodetool_setcachecapacity","title":"nodetool setcachecapacity <key MB> <row MB> <counter MB>","summary":"Set the key, row, and counter cache capacities in MB. All three are set in one call, so pass the current value for any cache you are not changing; 0 disables a cache. cassandra.nodetool_info reports the capacities in use.","description":"Set the key, row, and counter cache capacities in MB. All three are set in one call, so pass the current value for any cache you are not changing; 0 disables a cache. cassandra.nodetool_info reports the capacities in use.","kind":"exec","risk":"medium","side_effects":["Shrinking a cache evicts entries immediately, so reads run cold until it refills.","The key and counter caches live on the JVM heap — oversizing them adds GC pressure on the node.","Runtime-only — a restart returns the node to its cassandra.yaml values."],"args":[{"name":"key_cache_mb","type":"integer","required":true,"description":"Key cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}},{"name":"row_cache_mb","type":"integer","required":true,"description":"Row cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}},{"name":"counter_cache_mb","type":"integer","required":true,"description":"Counter cache capacity in MB; 0 disables it.","validation":{"min":0,"max":65536}}],"examples":[{"title":"512 MB key cache, row cache off, 128 MB counter cache","args":{"counter_cache_mb":128,"key_cache_mb":512,"row_cache_mb":0}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcachecapacity","{{ args.key_cache_mb }}","{{ args.row_cache_mb }}","{{ args.counter_cache_mb }}"]}},{"id":"cassandra.nodetool_setcompactionthreshold","title":"nodetool setcompactionthreshold <keyspace> <table> <min> <max>","summary":"Set the min and max SSTable count that triggers size-tiered compaction for one table. Raising the minimum makes the table compact less often and keeps more SSTables; lowering it compacts sooner. Read the current pair with cassandra.nodetool_getcompactionthreshold.","description":"Set the min and max SSTable count that triggers size-tiered compaction for one table. Raising the minimum makes the table compact less often and keeps more SSTables; lowering it compacts sooner. Read the current pair with cassandra.nodetool_getcompactionthreshold.","kind":"exec","risk":"medium","side_effects":["Applies to this table on this node only, and takes effect on the next compaction decision.","A higher minimum leaves more SSTables per read until the next compaction.","Runtime-only — a restart returns the table to its schema value."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to change.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"min_threshold","type":"integer","required":true,"description":"SSTables of one size tier needed before compaction starts (nodetool requires at least 2).","validation":{"min":2,"max":1000}},{"name":"max_threshold","type":"integer","required":true,"description":"Most SSTables compacted at once; must not be below min_threshold.","validation":{"min":2,"max":1000}}],"examples":[{"title":"Standard size-tiered thresholds","args":{"keyspace":"valorant_ks","max_threshold":32,"min_threshold":4,"table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthreshold","{{ args.keyspace }}","{{ args.table }}","{{ args.min_threshold }}","{{ args.max_threshold }}"]}},{"id":"cassandra.nodetool_setcompactionthroughput","title":"nodetool setcompactionthroughput <MB/s>","summary":"Set max compaction throughput. 0 = unlimited (use carefully).","description":"Set max compaction throughput. 0 = unlimited (use carefully).","kind":"exec","risk":"medium","side_effects":["In-flight + future compactions throttled to the new cap.","Lower values reduce IO pressure but grow SSTable count."],"args":[{"name":"mb_per_sec","type":"integer","required":true,"description":"MB/s; 0 = unlimited.","validation":{"min":0,"max":10000}}],"examples":[{"title":"Throttle to 16 MB/s","args":{"mb_per_sec":16}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthroughput","{{ args.mb_per_sec }}"]}},{"id":"cassandra.nodetool_setconcurrency","title":"nodetool setconcurrency <stage> <max>","summary":"Set the maximum number of threads one request-processing stage may use. Lower a stage to stop it crowding out the rest of the node, raise it when a stage is the bottleneck. List the stages and their current sizes with cassandra.nodetool_getconcurrency.","description":"Set the maximum number of threads one request-processing stage may use. Lower a stage to stop it crowding out the rest of the node, raise it when a stage is the bottleneck. List the stages and their current sizes with cassandra.nodetool_getconcurrency.","kind":"exec","risk":"medium","side_effects":["Applies immediately; work already queued on the stage runs under the new limit.","Starving a stage that serves live traffic (MUTATION, READ) shows up as client timeouts.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"stage","type":"string","required":true,"description":"Stage to resize, under the name nodetool accepts — MUTATION is the MutationStage that cassandra.nodetool_getconcurrency prints.","validation":{"enum":["READ","MUTATION","COUNTER_MUTATION","VIEW_MUTATION","GOSSIP","REQUEST_RESPONSE","ANTI_ENTROPY","MIGRATION","MISC","TRACING","INTERNAL_RESPONSE","IMMEDIATE","PAXOS_REPAIR"]}},{"name":"max_concurrency","type":"integer","required":true,"description":"Maximum threads for the stage.","validation":{"min":1,"max":1024}}],"examples":[{"title":"Hold write threads at 16","args":{"max_concurrency":16,"stage":"MUTATION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrency","{{ args.stage }}","{{ args.max_concurrency }}"]}},{"id":"cassandra.nodetool_setconcurrentcompactors","title":"nodetool setconcurrentcompactors <count>","summary":"Set how many compactions this node runs at once. Raise it to work off a compaction backlog, lower it to give CPU and disk back to reads and writes. Read the current value with cassandra.nodetool_getconcurrentcompactors.","description":"Set how many compactions this node runs at once. Raise it to work off a compaction backlog, lower it to give CPU and disk back to reads and writes. Read the current value with cassandra.nodetool_getconcurrentcompactors.","kind":"exec","risk":"medium","side_effects":["New compactions pick up the limit; compactions already running are not stopped.","Each compactor consumes CPU and disk IO, and shares the cap set by cassandra.nodetool_setcompactionthroughput.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"count","type":"integer","required":true,"description":"Number of concurrent compactors.","validation":{"min":1,"max":128}}],"examples":[{"title":"Allow four concurrent compactions","args":{"count":4}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrentcompactors","{{ args.count }}"]}},{"id":"cassandra.nodetool_setconcurrentviewbuilders","title":"nodetool setconcurrentviewbuilders <count>","summary":"Set how many materialized-view builds this node runs at once. Lower it when a view build is competing with live traffic, raise it to finish a build sooner. Read the current value with cassandra.nodetool_getconcurrentviewbuilders.","description":"Set how many materialized-view builds this node runs at once. Lower it when a view build is competing with live traffic, raise it to finish a build sooner. Read the current value with cassandra.nodetool_getconcurrentviewbuilders.","kind":"exec","risk":"medium","side_effects":["New view builds pick up the limit; builds already running are not stopped.","Each builder reads base-table data and writes view rows, adding CPU and disk IO.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"count","type":"integer","required":true,"description":"Number of concurrent view builders.","validation":{"min":1,"max":128}}],"examples":[{"title":"Hold view builds to one at a time","args":{"count":1}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setconcurrentviewbuilders","{{ args.count }}"]}},{"id":"cassandra.nodetool_sethintedhandoffthrottlekb","title":"nodetool sethintedhandoffthrottlekb <KiB/s>","summary":"Set the hinted-handoff delivery throttle in KiB/s, per delivery thread. Lower it when a peer coming back online is being flooded with replayed hints; raise it to clear a hint backlog faster.","description":"Set the hinted-handoff delivery throttle in KiB/s, per delivery thread. Lower it when a peer coming back online is being flooded with replayed hints; raise it to clear a hint backlog faster.","kind":"exec","risk":"medium","side_effects":["Applies to hint deliveries that start after the change.","Cassandra divides the rate across live peers, so the effective per-peer rate is lower in a large cluster.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"kb_per_sec","type":"integer","required":true,"description":"Throttle in KiB/s, per delivery thread.","validation":{"min":1,"max":1048576}}],"examples":[{"title":"Halve the default hint delivery rate","args":{"kb_per_sec":512}}],"search_terms":[],"command":{"binary":"nodetool","argv":["sethintedhandoffthrottlekb","{{ args.kb_per_sec }}"]}},{"id":"cassandra.nodetool_setinterdcstreamthroughput","title":"nodetool setinterdcstreamthroughput <value>","summary":"Set this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters during rebuild, bootstrap, and repair. Protects a shared or metered inter-datacenter link while local streaming keeps its own cap from cassandra.nodetool_setstreamthroughput. 0 disables throttling.","description":"Set this node's cross-datacenter streaming cap — the rate it sends SSTable data to peers in other datacenters during rebuild, bootstrap, and repair. Protects a shared or metered inter-datacenter link while local streaming keeps its own cap from cassandra.nodetool_setstreamthroughput. 0 disables throttling.","kind":"exec","risk":"medium","side_effects":["Applies immediately, to streams already in flight as well as new ones.","A cap under the current rate slows a running cross-datacenter rebuild; 0 lets it saturate the link.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"value","type":"integer","required":true,"description":"Cap in the unit named by cap; 0 disables throttling.","validation":{"min":0,"max":100000}},{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to set, and in which unit. stream_megabits is nodetool's own default (Mb/s); stream_mib is the same cap in MiB/s; entire_sstable_mib is the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Hold cross-datacenter streaming to 800 Mb/s","args":{"value":800}},{"title":"Hold cross-datacenter streaming to 40 MiB/s","args":{"cap":"stream_mib","value":40}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool setinterdcstreamthroughput $flag -- \"$VALUE\"\n"]}},{"id":"cassandra.nodetool_setlogginglevel","title":"nodetool setlogginglevel <logger> <level>","summary":"Set one logger's level. Use empty logger to reset all to the configured defaults.","description":"Set one logger's level. Use empty logger to reset all to the configured defaults.","kind":"exec","risk":"medium","side_effects":["Logger level changes immediately.","DEBUG/TRACE levels can dramatically increase log volume."],"args":[{"name":"logger","type":"string","required":true,"description":"Logger name (e.g. org.apache.cassandra.db, or \"root\").","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"level","type":"string","required":true,"description":"Level.","validation":{"enum":["TRACE","DEBUG","INFO","WARN","ERROR","OFF"]}}],"examples":[{"title":"Set DB layer to DEBUG","args":{"level":"DEBUG","logger":"org.apache.cassandra.db"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setlogginglevel","{{ args.logger }}","{{ args.level }}"]}},{"id":"cassandra.nodetool_setmaxhintwindow","title":"nodetool setmaxhintwindow <ms>","summary":"Set how long this node keeps writing hints for an unreachable peer, in milliseconds. Raise it to carry a peer through a longer maintenance window without a repair afterwards; 0 stops hint storage entirely. Read the current window with cassandra.nodetool_getmaxhintwindow.","description":"Set how long this node keeps writing hints for an unreachable peer, in milliseconds. Raise it to carry a peer through a longer maintenance window without a repair afterwards; 0 stops hint storage entirely. Read the current window with cassandra.nodetool_getmaxhintwindow.","kind":"exec","risk":"medium","side_effects":["A longer window stores more hints on disk and lengthens replay when the peer returns.","Writes made while a peer is down past the window are only recoverable by repair.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"window_ms","type":"integer","required":true,"description":"Hint window in milliseconds; 0 stops storing hints.","validation":{"min":0,"max":604800000}}],"examples":[{"title":"Hold hints for six hours","args":{"window_ms":21600000}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setmaxhintwindow","{{ args.window_ms }}"]}},{"id":"cassandra.nodetool_setsnapshotthrottle","title":"nodetool setsnapshotthrottle <links/s>","summary":"Set how many hard links per second snapshot and clearsnapshot may create. Lower it when taking a snapshot of a large node stalls the filesystem; 0 disables throttling. Read the current value with cassandra.nodetool_getsnapshotthrottle.","description":"Set how many hard links per second snapshot and clearsnapshot may create. Lower it when taking a snapshot of a large node stalls the filesystem; 0 disables throttling. Read the current value with cassandra.nodetool_getsnapshotthrottle.","kind":"exec","risk":"medium","side_effects":["Applies to snapshot work that starts after the change.","A low rate makes cassandra.nodetool_snapshot and cassandra.nodetool_clearsnapshot take proportionally longer on a table with many SSTables.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"links_per_sec","type":"integer","required":true,"description":"Hard links per second; 0 disables throttling.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Cap snapshot link creation","args":{"links_per_sec":200}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setsnapshotthrottle","{{ args.links_per_sec }}"]}},{"id":"cassandra.nodetool_setstreamthroughput","title":"nodetool setstreamthroughput <value>","summary":"Set this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Covers every stream the node sends; cross-datacenter streams are additionally capped by cassandra.nodetool_setinterdcstreamthroughput. 0 disables throttling.","description":"Set this node's outbound streaming cap — the rate it sends SSTable data during bootstrap, rebuild, repair, and decommission. Covers every stream the node sends; cross-datacenter streams are additionally capped by cassandra.nodetool_setinterdcstreamthroughput. 0 disables throttling.","kind":"exec","risk":"medium","side_effects":["Applies immediately, to streams already in flight as well as new ones.","A cap under the current rate slows a running rebuild or repair; 0 lets streaming saturate the link.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"value","type":"integer","required":true,"description":"Cap in the unit named by cap; 0 disables throttling.","validation":{"min":0,"max":100000}},{"name":"cap","type":"string","required":false,"default":"stream_megabits","description":"Which cap to set, and in which unit. stream_megabits is nodetool's own default (Mb/s); stream_mib is the same cap in MiB/s; entire_sstable_mib is the separate zero-copy entire-SSTable cap, which is always MiB/s.","validation":{"enum":["stream_megabits","stream_mib","entire_sstable_mib"]}}],"examples":[{"title":"Throttle streaming to 200 Mb/s","args":{"value":200}},{"title":"Throttle streaming to 64 MiB/s","args":{"cap":"stream_mib","value":64}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","case \"$CAP\" in\n  stream_megabits) flag=\"\" ;;\n  stream_mib) flag=\"-m\" ;;\n  entire_sstable_mib) flag=\"-e\" ;;\n  *) printf 'unsupported cap: %s\\n' \"$CAP\" >&2; exit 2 ;;\nesac\nexec nodetool setstreamthroughput $flag -- \"$VALUE\"\n"]}},{"id":"cassandra.nodetool_settimeout","title":"nodetool settimeout <type> <ms>","summary":"Set one of this node's request or internode timeouts, in milliseconds. Raise a timeout to ride out a slow period instead of failing queries, or lower it to fail fast. Read the current value with cassandra.nodetool_gettimeout.","description":"Set one of this node's request or internode timeouts, in milliseconds. Raise a timeout to ride out a slow period instead of failing queries, or lower it to fail fast. Read the current value with cassandra.nodetool_gettimeout.","kind":"exec","risk":"medium","side_effects":["Applies to requests that start after the change; requests in flight keep the old timeout.","A raised timeout holds threads and memory longer under load, which can turn a slow node into an unresponsive one.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"timeout_type","type":"string","required":true,"description":"Timeout to change.","validation":{"enum":["read","range","write","counterwrite","cascontention","truncate","internodeconnect","internodeuser","internodestreaminguser","misc"]}},{"name":"timeout_ms","type":"integer","required":true,"description":"Timeout in milliseconds. nodetool also takes 0, which for a request timeout means every request of that type fails at once rather than \"no limit\", so this action starts at 1.","validation":{"min":1,"max":3600000}}],"examples":[{"title":"Give reads two more seconds","args":{"timeout_ms":7000,"timeout_type":"read"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["settimeout","{{ args.timeout_type }}","{{ args.timeout_ms }}"]}},{"id":"cassandra.nodetool_settraceprobability","title":"nodetool settraceprobability <probability>","summary":"Set the fraction of requests this node traces, between 0 and 1. Turn tracing on briefly to see where latency goes, then set it back to 0. Read the current value with cassandra.nodetool_gettraceprobability.","description":"Set the fraction of requests this node traces, between 0 and 1. Turn tracing on briefly to see where latency goes, then set it back to 0. Read the current value with cassandra.nodetool_gettraceprobability.","kind":"exec","risk":"medium","side_effects":["Every traced request writes rows to the system_traces keyspace, adding write load and disk use.","Values above about 0.01 are heavy on a busy node; 1 traces every request.","Runtime-only — a restart returns the node to its cassandra.yaml value."],"args":[{"name":"probability","type":"number","required":true,"description":"Fraction of requests to trace; 0 disables tracing.","validation":{"min":0,"max":1}}],"examples":[{"title":"Trace one request in a hundred","args":{"probability":0.01}},{"title":"Turn tracing back off","args":{"probability":0}}],"search_terms":[],"command":{"binary":"nodetool","argv":["settraceprobability","{{ args.probability }}"]}},{"id":"cassandra.nodetool_snapshot","title":"nodetool snapshot -t <name> [ks]","summary":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","description":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","kind":"exec","risk":"medium","side_effects":["Hard links created in each table's snapshots/<name>/ dir.","Disk usage grows as SSTables roll over (snapshot pins originals).","Use clearsnapshot to delete."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Backup snapshot","args":{"tag":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool snapshot -t \"$2\" \"$1\"; else nodetool snapshot -t \"$2\"; fi","emisar","{{ args.keyspace }}","{{ args.tag }}"]}},{"id":"cassandra.nodetool_status","title":"Cassandra node ring status","summary":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","description":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection to the local Cassandra node.","May fail if JMX auth is misconfigured.","Does not modify Cassandra data or cluster state."],"args":[{"name":"host","type":"string","required":false,"default":"127.0.0.1","description":"JMX host for nodetool.","validation":{"enum":["127.0.0.1","localhost"]}},{"name":"port","type":"integer","required":false,"default":7199,"description":"JMX port.","validation":{"allowed":[7199]}}],"examples":[{"title":"Check local Cassandra ring","args":{}}],"search_terms":["ring health","node down","cluster health"],"command":{"binary":"nodetool","argv":["-h","{{ args.host }}","-p","{{ args.port }}","status"]}},{"id":"cassandra.nodetool_statusautocompaction","title":"nodetool statusautocompaction [keyspace] [table]","summary":"Check whether automatic compaction is running — for the whole node, one keyspace, or one table. The read that catches a table left with autocompaction off after a bulk load.","description":"Check whether automatic compaction is running — for the whole node, one keyspace, or one table. The read that catches a table left with autocompaction off after a bulk load.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Keyspace to check; empty checks the whole node.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"table","type":"string","required":false,"default":"","description":"Table to check; needs keyspace, and empty checks every table in it.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}}],"examples":[{"title":"Node-wide","args":{}},{"title":"One table","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["statusautocompaction","{{ args.keyspace? }}","{{ args.table? }}"]}},{"id":"cassandra.nodetool_stop_compaction","title":"nodetool stop <operation>","summary":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","description":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","kind":"exec","risk":"high","side_effects":["In-flight ops of the named type are aborted.","SSTables in progress are abandoned (no partial result)."],"args":[{"name":"operation","type":"string","required":true,"description":"Operation type.","validation":{"enum":["COMPACTION","VALIDATION","CLEANUP","SCRUB","VERIFY","INDEX_BUILD","VIEW_BUILD","ANTICOMPACTION"]}}],"examples":[{"title":"Stop all compactions","args":{"operation":"COMPACTION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["stop","{{ args.operation }}"]}},{"id":"cassandra.nodetool_tablehistograms","title":"nodetool tablehistograms <ks> <table>","summary":"Show local-node read/write/sstable/partition-size histograms for one table.","description":"Show local-node read/write/sstable/partition-size histograms for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":["p99 latency","wide partitions"],"command":{"binary":"nodetool","argv":["tablehistograms","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_tablestats","title":"Cassandra table stats","summary":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","description":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Output can be large for clusters with many tables."],"args":[{"name":"keyspace","type":"string","required":false,"description":"Optional keyspace to scope to (omit for all keyspaces).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Inspect a single keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":["sstable count","tombstones","space used per table"],"command":{"binary":"nodetool","argv":["tablestats","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_toppartitions","title":"nodetool toppartitions <keyspace> <table> <duration>","summary":"Sample one table's traffic for a few seconds and print its busiest partitions by read and write frequency — the direct answer to \"which key is hot\" that cassandra.cqlsh_largest_partitions cannot give, since the biggest partition and the busiest one are rarely the same.","description":"Sample one table's traffic for a few seconds and print its busiest partitions by read and write frequency — the direct answer to \"which key is hot\" that cassandra.cqlsh_largest_partitions cannot give, since the biggest partition and the busiest one are rarely the same.","kind":"exec","risk":"medium","side_effects":["Turns on request sampling for the named table for the duration, then reports and stops.","Sampling adds bookkeeping to every read and write on that table while it runs.","Blocks for the whole sampling duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table to sample.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"duration_ms","type":"integer","required":false,"default":5000,"description":"How long to sample, in milliseconds.","validation":{"min":1000,"max":60000}},{"name":"top_count","type":"integer","required":false,"default":10,"description":"How many partitions to list per sampler.","validation":{"min":1,"max":100}}],"examples":[{"title":"Busiest partitions over five seconds","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["toppartitions","-k","{{ args.top_count }}","--","{{ args.keyspace }}","{{ args.table }}","{{ args.duration_ms }}"]}},{"id":"cassandra.nodetool_tpstats","title":"Cassandra thread pool stats","summary":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","description":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect thread pool pressure","args":{}}],"search_terms":["dropped mutations","dropped messages"],"command":{"binary":"nodetool","argv":["tpstats"]}},{"id":"cassandra.nodetool_truncatehints","title":"nodetool truncatehints [endpoint]","summary":"Delete the hints this node is holding — all of them, or only those for one endpoint. The release valve when a hint backlog is filling the disk or targets a node that will never come back. The deleted writes are gone from this node's hint store, so the peers they were for need a repair.","description":"Delete the hints this node is holding — all of them, or only those for one endpoint. The release valve when a hint backlog is filling the disk or targets a node that will never come back. The deleted writes are gone from this node's hint store, so the peers they were for need a repair.","kind":"exec","risk":"high","side_effects":["Pending hints are deleted; the writes they carried are not delivered.","Every peer whose hints were dropped is left inconsistent until a repair runs.","Frees the disk the hint files were using."],"args":[{"name":"endpoint","type":"string","required":false,"default":"","description":"IP address or hostname whose hints to delete; empty deletes every pending hint on this node.","validation":{"pattern":"^([A-Za-z0-9._:-]{1,255})?$","max_length":255}}],"examples":[{"title":"Drop hints for one dead peer","args":{"endpoint":"10.1.4.7"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["truncatehints","--","{{ args.endpoint? }}"]}},{"id":"cassandra.nodetool_upgradesstables","title":"nodetool upgradesstables <keyspace> [table]","summary":"Rewrite SSTables that are still in an older on-disk format into the current one — the step after a major-version upgrade, and what lets the old format's read path be retired.","description":"Rewrite SSTables that are still in an older on-disk format into the current one — the step after a major-version upgrade, and what lets the old format's read path be retired.","kind":"exec","risk":"high","side_effects":["Rewrites every out-of-date SSTable of the named tables — sustained disk and CPU, and hours on a large node.","Needs free disk space for the rewritten files while it runs.","Does nothing when every file is already current, unless include_all is set."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to upgrade.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Single table to upgrade; empty upgrades every table in the keyspace.","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"include_all","type":"boolean","required":false,"default":false,"description":"Rewrite every SSTable, including files already in the current format."}],"examples":[{"title":"Upgrade one table's SSTables","args":{"keyspace":"valorant_ks","table":"matches"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\n[ \"$INCLUDE_ALL\" = \"true\" ] && flags=\"-a\"\nset -- \"$KEYSPACE\"\n[ -n \"$TABLE\" ] && set -- \"$@\" \"$TABLE\"\nexec nodetool upgradesstables $flags -- \"$@\"\n"]}},{"id":"cassandra.nodetool_verify","title":"nodetool verify [ks] [table]","summary":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","description":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","kind":"exec","risk":"medium","side_effects":["Reads every SSTable for the targeted scope.","IO-heavy; CPU light."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Verify one ks","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool verify \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool verify \"$2\"; else nodetool verify; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_version","title":"nodetool version","summary":"Show the Cassandra version string for the node.","description":"Show the Cassandra version string for the node.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["version"]}},{"id":"cassandra.nodetool_viewbuildstatus","title":"nodetool viewbuildstatus <keyspace> <view>","summary":"Show whether a materialized view has finished building, per node. Exits non-zero while the build is still running, and names the nodes that are behind.","description":"Show whether a materialized view has finished building, per node. Exits non-zero while the build is still running, and names the nodes that are behind.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace holding the view.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"view","type":"string","required":true,"description":"Materialized view name.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"View build progress","args":{"keyspace":"valorant_ks","view":"matches_by_player"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["viewbuildstatus","--","{{ args.keyspace }}","{{ args.view }}"]}}]},{"version":"0.4.17","content_hash":"sha256:004dd2be914847a029b679f21bb3a323fba4e5da387abcc765c9c560d277929d","tarball_url":"https://registry.emisar.dev/v1/packs/cassandra/0.4.17/004dd2be914847a029b679f21bb3a323fba4e5da387abcc765c9c560d277929d/pack.tar.gz","actions":[{"id":"cassandra.analyze_disk_pressure","title":"Analyze Cassandra disk pressure","summary":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","description":"Run a packaged shell script that inspects filesystem usage of the Cassandra data and commitlog directories. Read-only. Use as a first step when disk pressure is suspected. Output is human-readable; do not parse it.","kind":"script","risk":"low","side_effects":["Reads filesystem metadata (df, du counts).","Does not modify Cassandra data or configuration.","May create temporary files inside the runner's work directory."],"args":[{"name":"keyspace_filter","type":"string","required":false,"default":"","description":"Optional keyspace name to focus the analysis on.","validation":{"pattern":"^[a-zA-Z0-9_.*-]{0,80}$"}}],"examples":[{"title":"Analyze without keyspace filter","args":{}}],"search_terms":["disk full","running out of space"]},{"id":"cassandra.cqlsh_describe_keyspace","title":"cqlsh -e \"DESCRIBE KEYSPACE <ks>\"","summary":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","description":"Show the full DDL for one keyspace (tables, types, indexes, materialized views).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace DDL","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACE '\"$1\"';' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\"","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.cqlsh_describe_schema","title":"cqlsh -e \"DESCRIBE SCHEMA\"","summary":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","description":"Dump the full schema as CQL. Note: large clusters produce big output; rely on the byte cap.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Full schema","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE SCHEMA;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_keyspaces","title":"cqlsh -e \"DESCRIBE KEYSPACES\"","summary":"List all keyspaces.","description":"List all keyspaces.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Keyspaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'DESCRIBE KEYSPACES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_list_roles","title":"cqlsh -e \"LIST ROLES\"","summary":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","description":"List all roles + their grants (requires CassandraAuthorizer/Authenticator).","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Roles","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'LIST ROLES;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_system_peers","title":"SELECT * FROM system.peers_v2","summary":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","description":"List the peer nodes as this coordinator sees them: dc, rack, schema version, tokens.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Peers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers_v2;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\" || cqlsh -e 'SELECT peer, data_center, rack, schema_version, host_id, tokens FROM system.peers;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.cqlsh_system_size_estimates","title":"SELECT * FROM system.size_estimates","summary":"Show per-table partition + size estimates from the gossiped size_estimates table.","description":"Show per-table partition + size estimates from the gossiped size_estimates table.","kind":"exec","risk":"low","side_effects":["One CQL query.","Read-only."],"args":[],"examples":[{"title":"Size estimates","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cqlsh -e 'SELECT keyspace_name, table_name, range_start, range_end, mean_partition_size, partitions_count FROM system.size_estimates LIMIT 200;' \"${CQLSH_HOST:-127.0.0.1}\" \"${CQLSH_PORT:-9042}\""]}},{"id":"cassandra.nodetool_assassinate","title":"nodetool assassinate <address>","summary":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","description":"Forcibly removes a dead node from gossip without streaming data. ONLY use when the node is permanently gone AND removenode failed. Risks: orphaned data, hint bleed, token misownership.","kind":"exec","risk":"critical","side_effects":["Node entry purged from gossip.","No data streaming — data that was on the node is gone.","Other replicas eventually catch up via repair."],"args":[{"name":"address","type":"string","required":true,"description":"IP address of the dead node.","validation":{"pattern":"^[0-9]{1,3}(\\.[0-9]{1,3}){3}$"}}],"examples":[{"title":"Remove permanently dead node","args":{"address":"10.0.0.42"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["assassinate","{{ args.address }}"]}},{"id":"cassandra.nodetool_cleanup","title":"nodetool cleanup [ks]","summary":"Remove data no longer owned by this node (after a topology change). IO-heavy.","description":"Remove data no longer owned by this node (after a topology change). IO-heavy.","kind":"exec","risk":"high","side_effects":["SSTables rewritten without data that moved off this node.","Heavy IO + CPU; may take hours on large tables.","Free space requirement during cleanup."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Cleanup post-bootstrap","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool cleanup \"$1\"; else nodetool cleanup; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_clearsnapshot","title":"nodetool clearsnapshot -t <name>","summary":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","description":"Delete one snapshot tag from all keyspaces. Frees disk that was pinned by the snapshot.","kind":"exec","risk":"high","side_effects":["Snapshot hard links removed.","Disk space reclaims as the underlying SSTables become orphaned."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag to delete.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Delete tag","args":{"tag":"old-backup"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["clearsnapshot","-t","{{ args.tag }}"]}},{"id":"cassandra.nodetool_compact","title":"nodetool compact <ks> [table]","summary":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","description":"Force major compaction. For STCS this merges everything into one big SSTable — almost always a mistake. Prefer per-token-range compaction or letting the strategy run.","kind":"exec","risk":"high","side_effects":["Heavy disk + CPU for the duration.","For STCS, creates one giant SSTable that is hard to compact later.","For LCS, may be fine."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Major-compact one table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool compact \"$2\" \"$1\"; else nodetool compact \"$2\"; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_compactionhistory","title":"nodetool compactionhistory","summary":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","description":"List the last few compactions with bytes-in/out, duration, and dropped tombstones.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Recent compactions","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["compactionhistory"]}},{"id":"cassandra.nodetool_compactionstats","title":"Cassandra compaction statistics","summary":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","description":"Run `nodetool compactionstats`. Pending compactions in the dozens-to-hundreds indicate the node is behind. Triggering repair on a node already behind on compactions usually makes things worse — wait for the queue to drain before recommending repair.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect compaction backlog","args":{}}],"search_terms":["compactions backed up","compaction backlog","pending compactions"],"command":{"binary":"nodetool","argv":["compactionstats"]}},{"id":"cassandra.nodetool_decommission","title":"nodetool decommission","summary":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","description":"Stream this node's data to other replicas, then leave the ring. NOT reversible without re-bootstrapping.","kind":"exec","risk":"critical","side_effects":["All data streams to remaining replicas.","Heavy network + disk on this and peer nodes.","Node leaves the ring; tokens are reassigned.","Can take many hours on big datasets."],"args":[],"examples":[{"title":"Remove this node","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["decommission"]}},{"id":"cassandra.nodetool_describecluster","title":"nodetool describecluster","summary":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","description":"Show the cluster name, partitioner, snitch, and schema versions per host. Schema disagreement here is a sign of partial DDL propagation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Cluster summary","args":{}}],"search_terms":["schema disagreement","schema mismatch"],"command":{"binary":"nodetool","argv":["describecluster"]}},{"id":"cassandra.nodetool_describering","title":"nodetool describering <keyspace>","summary":"Show token range → replica endpoint mapping for one keyspace.","description":"Show token range → replica endpoint mapping for one keyspace.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One keyspace's ring","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["describering","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_drain","title":"nodetool drain","summary":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","description":"Stop accepting writes, flush memtables, persist commit log positions. Node is unusable until restart.","kind":"exec","risk":"critical","side_effects":["Node stops accepting writes immediately.","All memtables flushed.","Native + Thrift transports closed.","Only restart restores the node."],"args":[],"examples":[{"title":"Drain before restart","args":{}}],"search_terms":["safe shutdown","flush before restart"],"command":{"binary":"nodetool","argv":["drain"]}},{"id":"cassandra.nodetool_failuredetector","title":"nodetool failuredetector","summary":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","description":"Show phi accrual failure detector scores per peer. Phi > 8 ≈ marked down.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Phi scores","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["failuredetector"]}},{"id":"cassandra.nodetool_flush","title":"nodetool flush [ks] [table]","summary":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","description":"Force memtable → SSTable flush. Without args: all keyspaces. Brief IO spike + writeahead replay simplification.","kind":"exec","risk":"high","side_effects":["Memtables for the targeted scope are flushed to disk.","Brief IO spike.","Commit log may be marked clean for the affected segments."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table (requires keyspace).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Flush one keyspace","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool flush \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool flush \"$2\"; else nodetool flush; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_getcompactionthroughput","title":"nodetool getcompactionthroughput","summary":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","description":"Show the current compaction throughput cap (MB/s; 0 = unlimited).","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Compaction throughput","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getcompactionthroughput"]}},{"id":"cassandra.nodetool_getconcurrentcompactors","title":"nodetool getconcurrentcompactors","summary":"Show the current concurrent_compactors setting.","description":"Show the current concurrent_compactors setting.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Concurrent compactors","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getconcurrentcompactors"]}},{"id":"cassandra.nodetool_getendpoints","title":"nodetool getendpoints <ks> <table> <key>","summary":"Show which replicas own a specific partition key. Use to confirm read/write routing.","description":"Show which replicas own a specific partition key. Use to confirm read/write routing.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"key","type":"string","required":true,"description":"Partition key (as a literal).","validation":{"pattern":"^[a-zA-Z0-9_:.][a-zA-Z0-9_\\-:.]{0,255}$"}}],"examples":[{"title":"Owning replicas","args":{"key":"user-1234","keyspace":"my_ks","table":"users"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getendpoints","{{ args.keyspace }}","{{ args.table }}","{{ args.key }}"]}},{"id":"cassandra.nodetool_getlogginglevels","title":"nodetool getlogginglevels","summary":"Show the current per-logger levels.","description":"Show the current per-logger levels.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Logger levels","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["getlogginglevels"]}},{"id":"cassandra.nodetool_gossipinfo","title":"nodetool gossipinfo","summary":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","description":"Show per-peer gossip state — schema version, status, load, dc, rack, generation.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Gossip view","args":{}}],"search_terms":["node stuck joining"],"command":{"binary":"nodetool","argv":["gossipinfo"]}},{"id":"cassandra.nodetool_info","title":"nodetool info","summary":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","description":"Show this node: uptime, heap, load, exceptions, key+row+counter cache hit rates.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"This node","args":{}}],"search_terms":["node uptime","heap usage"],"command":{"binary":"nodetool","argv":["info"]}},{"id":"cassandra.nodetool_invalidatecountercache","title":"nodetool invalidatecountercache","summary":"Drop the counter cache.","description":"Drop the counter cache.","kind":"exec","risk":"medium","side_effects":["Counter cache cleared.","Counter reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop counter cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatecountercache"]}},{"id":"cassandra.nodetool_invalidatekeycache","title":"nodetool invalidatekeycache","summary":"Drop the key cache. Reads pay cold-cache cost until it warms.","description":"Drop the key cache. Reads pay cold-cache cost until it warms.","kind":"exec","risk":"medium","side_effects":["Key cache cleared.","Next reads must do bloom-filter + summary + index lookups."],"args":[],"examples":[{"title":"Drop key cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidatekeycache"]}},{"id":"cassandra.nodetool_invalidaterowcache","title":"nodetool invalidaterowcache","summary":"Drop the row cache.","description":"Drop the row cache.","kind":"exec","risk":"medium","side_effects":["Row cache cleared.","Next reads pay cold-cache cost."],"args":[],"examples":[{"title":"Drop row cache","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["invalidaterowcache"]}},{"id":"cassandra.nodetool_listsnapshots","title":"nodetool listsnapshots","summary":"List all snapshots on this node with size + creation timestamp.","description":"List all snapshots on this node with size + creation timestamp.","kind":"exec","risk":"low","side_effects":["Reads disk metadata.","Read-only."],"args":[],"examples":[{"title":"All snapshots","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["listsnapshots"]}},{"id":"cassandra.nodetool_netstats","title":"nodetool netstats","summary":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","description":"Show streaming + read repair stats: completed/pending bytes, files transferred, pool stats.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Net stats","args":{}}],"search_terms":["streaming progress","streaming stuck","bootstrap progress"],"command":{"binary":"nodetool","argv":["netstats"]}},{"id":"cassandra.nodetool_proxyhistograms","title":"nodetool proxyhistograms","summary":"Show coordinator-side read/write latency histograms — what clients actually see.","description":"Show coordinator-side read/write latency histograms — what clients actually see.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Coordinator latencies","args":{}}],"search_terms":["p99 latency","latency percentiles","reads are slow","writes are slow"],"command":{"binary":"nodetool","argv":["proxyhistograms"]}},{"id":"cassandra.nodetool_rebuild","title":"nodetool rebuild [source_dc]","summary":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","description":"Re-bootstrap a node by streaming from another DC (or any DC if unspecified). Use after expanding into a new DC.","kind":"exec","risk":"high","side_effects":["Heavy streaming workload.","Existing data on this node is NOT removed first.","Best run on a node that has empty data dirs."],"args":[{"name":"source_dc","type":"string","required":false,"default":"","description":"Source DC name (empty = any).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rebuild from us-east","args":{"source_dc":"us-east"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool rebuild \"$1\"; else nodetool rebuild; fi","emisar","{{ args.source_dc }}"]}},{"id":"cassandra.nodetool_removenode","title":"nodetool removenode <host-id>","summary":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","description":"Remove a down node from the cluster and stream its data from other replicas. Preferred over assassinate when there's quorum.","kind":"exec","risk":"critical","side_effects":["Other replicas stream the dead node's data to their successors.","Heavy network + disk during stream.","Token range reassigned permanently."],"args":[{"name":"host_id","type":"string","required":true,"description":"Host ID UUID (from nodetool status).","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Remove a down node","args":{"host_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["remove dead node"],"command":{"binary":"nodetool","argv":["removenode","{{ args.host_id }}"]}},{"id":"cassandra.nodetool_repair","title":"Cassandra repair","summary":"Wrap `nodetool repair`.","description":"Wrap `nodetool repair`. The most dangerous \"normal\" operation — repair reconciles data between replicas, can take hours, produces significant cluster-wide load, may interact poorly with TTL/tombstone-heavy tables, and can worsen latency on every replica it touches. Always inspect ring status, compactions, disk, and logs first. Prefer mode=preview — a dry run that estimates the repair without performing it (requires Cassandra 4.0+) — before a real repair. Refuse to proceed if the ring has DN/UJ/UL/UM nodes.","kind":"exec","risk":"high","side_effects":["Repair coordinates with replicas across the cluster.","Generates significant network, CPU, and disk I/O.","Schedules anti-compaction and validation tasks.","Can run for minutes to hours depending on dataset size.","May worsen latency on the local node and on replica nodes for the duration."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace to repair.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional single table to repair (empty = whole keyspace).","validation":{"pattern":"^([a-zA-Z][a-zA-Z0-9_]{0,47})?$"}},{"name":"mode","type":"string","required":false,"default":"preview","description":"Repair mode.","validation":{"enum":["preview","full","incremental"]}},{"name":"primary_range","type":"boolean","required":false,"default":true,"description":"Restrict to the primary token range (recommended)."},{"name":"parallelism","type":"string","required":false,"default":"sequential","description":"Parallelism mode.","validation":{"enum":["sequential","parallel","dc_parallel"]}}],"examples":[{"title":"Dry-run repair preview on one keyspace","args":{"keyspace":"valorant_ks","mode":"preview"}}],"search_terms":["anti-entropy","inconsistent replicas","data consistency"],"command":{"binary":"/bin/sh","argv":["-c","flags=\"\"\ncase \"$MODE\" in\n  preview) flags=\"--preview\" ;;\n  full) flags=\"-full\" ;;\n  # Incremental is nodetool's own default on 4.x and 5.x and has no flag\n  # of its own (-inc went away after 3.x). Named anyway: falling through\n  # meant the operator asked for incremental and silently got whatever\n  # this node's version defaults to, and the next enum value added here\n  # would have inherited the same silence.\n  incremental) flags=\"\" ;;\n  *) printf 'unsupported repair mode: %s\\n' \"$MODE\" >&2; exit 2 ;;\nesac\n[ \"$PR\" = \"true\" ] && flags=\"$flags -pr\"\ncase \"$PAR\" in\n  sequential) flags=\"$flags -seq\" ;;\n  dc_parallel) flags=\"$flags -dcpar\" ;;\nesac\nset -- \"$KS\"\n[ -n \"$TBL\" ] && set -- \"$@\" \"$TBL\"\nexec nodetool repair $flags \"$@\"\n"]}},{"id":"cassandra.nodetool_ring","title":"nodetool ring [keyspace]","summary":"Show the token ring with owner host per token.","description":"Show the token ring with owner host per token.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (default — all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Ring","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool ring \"$1\"; else nodetool ring; fi","emisar","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_setcompactionthroughput","title":"nodetool setcompactionthroughput <MB/s>","summary":"Set max compaction throughput. 0 = unlimited (use carefully).","description":"Set max compaction throughput. 0 = unlimited (use carefully).","kind":"exec","risk":"medium","side_effects":["In-flight + future compactions throttled to the new cap.","Lower values reduce IO pressure but grow SSTable count."],"args":[{"name":"mb_per_sec","type":"integer","required":true,"description":"MB/s; 0 = unlimited.","validation":{"min":0,"max":10000}}],"examples":[{"title":"Throttle to 16 MB/s","args":{"mb_per_sec":16}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setcompactionthroughput","{{ args.mb_per_sec }}"]}},{"id":"cassandra.nodetool_setlogginglevel","title":"nodetool setlogginglevel <logger> <level>","summary":"Set one logger's level. Use empty logger to reset all to the configured defaults.","description":"Set one logger's level. Use empty logger to reset all to the configured defaults.","kind":"exec","risk":"medium","side_effects":["Logger level changes immediately.","DEBUG/TRACE levels can dramatically increase log volume."],"args":[{"name":"logger","type":"string","required":true,"description":"Logger name (e.g. org.apache.cassandra.db, or \"root\").","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"level","type":"string","required":true,"description":"Level.","validation":{"enum":["TRACE","DEBUG","INFO","WARN","ERROR","OFF"]}}],"examples":[{"title":"Set DB layer to DEBUG","args":{"level":"DEBUG","logger":"org.apache.cassandra.db"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["setlogginglevel","{{ args.logger }}","{{ args.level }}"]}},{"id":"cassandra.nodetool_snapshot","title":"nodetool snapshot -t <name> [ks]","summary":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","description":"Atomic hard-link snapshot of SSTables. Cheap to take, expensive if left around.","kind":"exec","risk":"medium","side_effects":["Hard links created in each table's snapshots/<name>/ dir.","Disk usage grows as SSTables roll over (snapshot pins originals).","Use clearsnapshot to delete."],"args":[{"name":"tag","type":"string","required":true,"description":"Snapshot tag.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Backup snapshot","args":{"tag":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool snapshot -t \"$2\" \"$1\"; else nodetool snapshot -t \"$2\"; fi","emisar","{{ args.keyspace }}","{{ args.tag }}"]}},{"id":"cassandra.nodetool_status","title":"Cassandra node ring status","summary":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","description":"Run `nodetool status`. Read-only — does not change Cassandra state. Use this before suggesting repair, cleanup, decommission, replacement, or topology changes. If any node is DN/UJ/UL/UM, do not recommend repair until the failure mode is understood.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection to the local Cassandra node.","May fail if JMX auth is misconfigured.","Does not modify Cassandra data or cluster state."],"args":[{"name":"host","type":"string","required":false,"default":"127.0.0.1","description":"JMX host for nodetool.","validation":{"enum":["127.0.0.1","localhost"]}},{"name":"port","type":"integer","required":false,"default":7199,"description":"JMX port.","validation":{"allowed":[7199]}}],"examples":[{"title":"Check local Cassandra ring","args":{}}],"search_terms":["ring health","node down","cluster health"],"command":{"binary":"nodetool","argv":["-h","{{ args.host }}","-p","{{ args.port }}","status"]}},{"id":"cassandra.nodetool_stop_compaction","title":"nodetool stop <operation>","summary":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","description":"Stop in-flight operations of one type (COMPACTION, CLEANUP, VERIFY, etc).","kind":"exec","risk":"high","side_effects":["In-flight ops of the named type are aborted.","SSTables in progress are abandoned (no partial result)."],"args":[{"name":"operation","type":"string","required":true,"description":"Operation type.","validation":{"enum":["COMPACTION","VALIDATION","CLEANUP","SCRUB","VERIFY","INDEX_BUILD","VIEW_BUILD","ANTICOMPACTION"]}}],"examples":[{"title":"Stop all compactions","args":{"operation":"COMPACTION"}}],"search_terms":[],"command":{"binary":"nodetool","argv":["stop","{{ args.operation }}"]}},{"id":"cassandra.nodetool_tablehistograms","title":"nodetool tablehistograms <ks> <table>","summary":"Show local-node read/write/sstable/partition-size histograms for one table.","description":"Show local-node read/write/sstable/partition-size histograms for one table.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[{"name":"keyspace","type":"string","required":true,"description":"Keyspace.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"One table","args":{"keyspace":"my_ks","table":"users"}}],"search_terms":["p99 latency","wide partitions"],"command":{"binary":"nodetool","argv":["tablehistograms","{{ args.keyspace }}","{{ args.table }}"]}},{"id":"cassandra.nodetool_tablestats","title":"Cassandra table stats","summary":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","description":"Run `nodetool tablestats`, optionally scoped to a single keyspace. Read-only. Output can be large for clusters with many tables. Use to identify tables with large sstable counts or large on-disk size — repairs on very large or tombstone-heavy tables are risky and worth surfacing before a repair recommendation.","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Output can be large for clusters with many tables."],"args":[{"name":"keyspace","type":"string","required":false,"description":"Optional keyspace to scope to (omit for all keyspaces).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$"}}],"examples":[{"title":"Inspect a single keyspace","args":{"keyspace":"valorant_ks"}}],"search_terms":["sstable count","tombstones","space used per table"],"command":{"binary":"nodetool","argv":["tablestats","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_tpstats","title":"Cassandra thread pool stats","summary":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","description":"Run `nodetool tpstats` for active/pending/blocked counts per pool. High pending or blocked counts on MutationStage, CompactionExecutor, or ReadStage usually indicate ongoing pressure — investigate the cause before recommending operations that add load (repair, large reads, compaction tuning).","kind":"exec","risk":"low","side_effects":["Starts a short-lived JMX connection.","Touches no files."],"args":[],"examples":[{"title":"Inspect thread pool pressure","args":{}}],"search_terms":["dropped mutations","dropped messages"],"command":{"binary":"nodetool","argv":["tpstats"]}},{"id":"cassandra.nodetool_verify","title":"nodetool verify [ks] [table]","summary":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","description":"Verify SSTable checksums for one (or all) tables. Detects on-disk corruption.","kind":"exec","risk":"medium","side_effects":["Reads every SSTable for the targeted scope.","IO-heavy; CPU light."],"args":[{"name":"keyspace","type":"string","required":false,"default":"","description":"Optional keyspace (empty = all).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}},{"name":"table","type":"string","required":false,"default":"","description":"Optional table.","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9_]{0,47}$|^$"}}],"examples":[{"title":"Verify one ks","args":{"keyspace":"my_ks"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -n ''\"$1\"'' ]; then nodetool verify \"$2\" \"$1\"; elif [ -n ''\"$2\"'' ]; then nodetool verify \"$2\"; else nodetool verify; fi","emisar","{{ args.table }}","{{ args.keyspace }}"]}},{"id":"cassandra.nodetool_version","title":"nodetool version","summary":"Show the Cassandra version string for the node.","description":"Show the Cassandra version string for the node.","kind":"exec","risk":"low","side_effects":["One JMX call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"nodetool","argv":["version"]}}]}],"retired_below":"0.4.10"},{"id":"clickhouse","name":"ClickHouse analytics DB","version":"0.2.13","description":"ClickHouse server + table introspection — metrics, errors, slow & failed queries, parts/partitions, merges, mutations, replication queue, Keeper/ZK health, detached parts, distributed-send backlog, backups — plus narrow mutators (OPTIMIZE, KILL QUERY, SYSTEM RELOAD CONFIG, replica ops). Auth via CH_HOST + CH_USER + CH_PASSWORD env vars on the runner host. Uses clickhouse-client with --query to keep arg surface minimal.","vendor":"emisar","homepage":"https://emisar.dev/packs/clickhouse","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/clickhouse","content_hash":"sha256:0a427581ac3e5d78d467e7bd77c6a8e8798d420435c7e4cc0418a98e6b72fc39","tarball_url":"https://registry.emisar.dev/v1/packs/clickhouse/0.2.13/0a427581ac3e5d78d467e7bd77c6a8e8798d420435c7e4cc0418a98e6b72fc39/pack.tar.gz","requires":{"os":["linux"],"binaries":["clickhouse-client"]},"detect":{"binaries":[],"processes":["clickhouse-server"],"ports":[8123]},"setup":{"summary":"Each action reads `CH_HOST`, `CH_USER`, and `CH_PASSWORD` on the runner host and passes host/user to clickhouse-client as --host/--user; the password is handed over via the client's native CLICKHOUSE_PASSWORD env var so it never lands on the process command line. Host and user fall back to localhost and the default user, so a local server with the default account needs no setup at all.","env":[{"name":"CH_HOST","description":"Server host passed to --host.","default":"localhost"},{"name":"CH_USER","description":"User passed to --user.","default":"default"},{"name":"CH_PASSWORD","description":"Password handed to clickhouse-client via CLICKHOUSE_PASSWORD (kept off argv). Leave unset for a passwordless account."}],"notes":["Any of `CH_HOST` / `CH_USER` / `CH_PASSWORD` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Connection always uses clickhouse-client's default native port (9000); there is no port env var in this pack.","The user needs SELECT on the system tables for the reads, plus rights for the mutators (KILL QUERY, OPTIMIZE, SYSTEM ... for replica/config actions) you enable.","The replication/Keeper reads (replication_queue, zookeeper_connection, keeper_status, detached_parts) only return data on a ReplicatedMergeTree + Keeper/ZooKeeper deployment; on a single non-replicated server they come back empty, which is correct, not an error."],"verify":"ch.uptime"},"actions":[{"id":"ch.asynchronous_metrics","title":"SELECT * FROM system.asynchronous_metrics","summary":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","description":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Async metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value, description FROM system.asynchronous_metrics ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.backups","title":"SELECT * FROM system.backups","summary":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","description":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Backup/restore status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT id, name, status, substring(error, 1, 300) AS error, start_time, end_time, num_files, total_size FROM system.backups ORDER BY start_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.detached_parts","title":"SELECT * FROM system.detached_parts","summary":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","description":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Detached parts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition_id, name, reason, disk, bytes_on_disk FROM system.detached_parts ORDER BY bytes_on_disk DESC LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.dictionaries","title":"SELECT * FROM system.dictionaries","summary":"List loaded dictionaries with status, element count, source.","description":"List loaded dictionaries with status, element count, source.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Dictionaries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, status, element_count, source FROM system.dictionaries FORMAT JSONEachRow\""]}},{"id":"ch.disks","title":"SELECT * FROM system.disks","summary":"List configured disks with free/used bytes + paths.","description":"List configured disks with free/used bytes + paths.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, path, free_space, total_space, type FROM system.disks FORMAT JSONEachRow\""]}},{"id":"ch.distribution_queue","title":"SELECT * FROM system.distribution_queue","summary":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","description":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Distributed send backlog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_blocked, error_count, data_files, data_compressed_bytes, broken_data_files, last_exception_time, substring(last_exception, 1, 300) AS last_exception FROM system.distribution_queue ORDER BY data_files DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.errors","title":"SELECT * FROM system.errors","summary":"List error codes seen since startup with counts and the last message. Spot error storms.","description":"List error codes seen since startup with counts and the last message. Spot error storms.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recent errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, code, value, last_error_time, substring(last_error_message, 1, 300) AS last_message, remote FROM system.errors WHERE value > 0 ORDER BY last_error_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.keeper_status","title":"List a Keeper/ZooKeeper path (system.zookeeper)","summary":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","description":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"ZooKeeper/Keeper path to list (e.g. /clickhouse/tables).","validation":{"pattern":"^/[A-Za-z0-9_./-]{0,255}$"}}],"examples":[{"title":"List the clickhouse Keeper root","args":{"path":"/clickhouse"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, value, numChildren, ctime, mtime, version, czxid, mzxid FROM system.zookeeper WHERE path = '$ZKPATH' ORDER BY name LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.kill_mutation","title":"Cancel a stuck mutation (KILL MUTATION)","summary":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","description":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","kind":"exec","risk":"critical","side_effects":["The matching mutation is cancelled; its partial work is abandoned.","Targets exactly one mutation — all three identity args are required.","Reversible only by re-issuing the ALTER that created the mutation."],"args":[{"name":"database","type":"string","required":true,"description":"Database of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"table","type":"string","required":true,"description":"Table of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"mutation_id","type":"string","required":true,"description":"mutation_id from ch.stuck_mutations (e.g. mutation_3.txt).","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a stuck mutation","args":{"database":"default","mutation_id":"mutation_3.txt","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL MUTATION WHERE database = '${1}' AND table = '${2}' AND mutation_id = '${3}'\"","emisar","{{ args.database }}","{{ args.table }}","{{ args.mutation_id }}"]}},{"id":"ch.kill_query","title":"KILL QUERY WHERE query_id = '<id>'","summary":"Cancel one running query by ID.","description":"Cancel one running query by ID.","kind":"exec","risk":"high","side_effects":["Targeted query is terminated.","Client receives a cancellation error."],"args":[{"name":"query_id","type":"string","required":true,"description":"Query ID (from system.processes).","validation":{"pattern":"^[a-zA-Z0-9\\-]{1,64}$"}}],"examples":[{"title":"Cancel one query","args":{"query_id":"abc123-def4-5678"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL QUERY WHERE query_id = '$Q' SYNC\""]}},{"id":"ch.merge_queue","title":"SELECT * FROM system.merges","summary":"List in-progress + queued merges.","description":"List in-progress + queued merges.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Active merges","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, elapsed, progress, num_parts, source_part_names, result_part_name, total_size_bytes_compressed, memory_usage FROM system.merges FORMAT JSONEachRow\""]}},{"id":"ch.mutation_queue","title":"SELECT * FROM system.mutations","summary":"List in-progress + pending mutations (ALTER TABLE).","description":"List in-progress + pending mutations (ALTER TABLE).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Pending mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, is_done, parts_to_do, latest_failed_part, latest_fail_reason FROM system.mutations WHERE NOT is_done FORMAT JSONEachRow\""]}},{"id":"ch.optimize_table","title":"OPTIMIZE TABLE FINAL","summary":"Force merge of all parts into one. Heavy disk + CPU.","description":"Force merge of all parts into one. Heavy disk + CPU.","kind":"exec","risk":"high","side_effects":["Background merge runs synchronously; can take minutes-to-hours on large tables.","Temporary doubling of disk space during the merge."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}}],"examples":[{"title":"Optimize table","args":{"database":"default","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"OPTIMIZE TABLE ${1}.${2} FINAL\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"ch.parts_by_partition","title":"Active part count per partition (system.parts)","summary":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","description":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Parts per partition","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition, count() AS parts, sum(rows) AS rows, sum(bytes_on_disk) AS bytes FROM system.parts WHERE active GROUP BY database, table, partition ORDER BY parts DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.parts_summary","title":"SELECT system.parts (by table)","summary":"List active part counts + sizes per table. Use to spot too-many-parts.","description":"List active part counts + sizes per table. Use to spot too-many-parts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top tables by size","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, sum(rows) as rows, sum(bytes_on_disk) as bytes, count() as parts FROM system.parts WHERE active GROUP BY database, table ORDER BY bytes DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.processes","title":"SELECT * FROM system.processes","summary":"List currently-running queries. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"List currently-running queries. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT query_id, user, elapsed, memory_usage, read_rows, query FROM system.processes ORDER BY elapsed DESC FORMAT JSONEachRow\""]}},{"id":"ch.query_errors","title":"Failed queries from system.query_log (last hour)","summary":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries. Rated medium because the output carries live query text and exception messages, which can include literal request values no redaction list can enumerate.","description":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries. Rated medium because the output carries live query text and exception messages, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Failed queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, type, user, query_id, exception_code, substring(exception, 1, 300) AS exception, substring(query, 1, 200) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type IN (3, 4) ORDER BY event_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.reload_config","title":"SYSTEM RELOAD CONFIG","summary":"Re-read config.xml + users.xml without restarting; whatever is now on disk — including changed users and access grants — takes effect on the live server immediately.","description":"Re-read config.xml + users.xml without restarting; whatever is now on disk — including changed users and access grants — takes effect on the live server immediately.","kind":"exec","risk":"high","side_effects":["Config + user definitions reloaded.","Open sessions unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RELOAD CONFIG\""]}},{"id":"ch.replicas_status","title":"SELECT * FROM system.replicas","summary":"Show per-replica state — leader, queue size, log delays, errors.","description":"Show per-replica state — leader, queue size, log delays, errors.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replica health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_leader, is_readonly, future_parts, parts_to_check, queue_size, absolute_delay, log_max_index, log_pointer, total_replicas, active_replicas FROM system.replicas FORMAT JSONEachRow\""]}},{"id":"ch.replication_queue","title":"SELECT * FROM system.replication_queue","summary":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","description":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replication queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, type, create_time, new_part_name, num_tries, is_currently_executing, num_postponed, postpone_reason, last_attempt_time, substring(last_exception, 1, 300) AS last_exception FROM system.replication_queue ORDER BY num_tries DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.slow_queries","title":"system.query_log slowest queries","summary":"List top 50 slowest queries from the last hour. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"List top 50 slowest queries from the last hour. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slow queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, query_duration_ms, user, read_rows, memory_usage, query_id, substring(query, 1, 300) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type = 2 ORDER BY query_duration_ms DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.stuck_mutations","title":"Failing mutations (system.mutations)","summary":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","description":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Stuck mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, parts_to_do, latest_failed_part, latest_fail_time, substring(latest_fail_reason, 1, 300) AS fail_reason FROM system.mutations WHERE NOT is_done AND latest_fail_reason != '' ORDER BY create_time ASC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.system_drop_replica","title":"SYSTEM DROP REPLICA <name>","summary":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","description":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","kind":"exec","risk":"critical","side_effects":["Replica metadata deleted from ZK.","Replica cannot rejoin without recreating tables.","Other replicas continue normally."],"args":[{"name":"replica","type":"string","required":true,"description":"Replica name as listed in system.replicas.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Drop dead replica","args":{"replica":"replica-7","table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM DROP REPLICA '$RPL' FROM TABLE $TBL\""]}},{"id":"ch.system_events","title":"SELECT * FROM system.events","summary":"List process-lifetime event counters.","description":"List process-lifetime event counters.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event, value FROM system.events ORDER BY value DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.system_flush_logs","title":"SYSTEM FLUSH LOGS","summary":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","description":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","kind":"exec","risk":"medium","side_effects":["One write to each *_log table.","Brief I/O spike."],"args":[],"examples":[{"title":"Flush log tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM FLUSH LOGS\""]}},{"id":"ch.system_metrics","title":"SELECT * FROM system.metrics","summary":"Show per-metric current values (gauges + counters).","description":"Show per-metric current values (gauges + counters).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value FROM system.metrics WHERE value != 0 ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.system_restart_replica","title":"SYSTEM RESTART REPLICA <table>","summary":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","description":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","kind":"exec","risk":"high","side_effects":["Local replica state reset.","May trigger large data re-fetch from peers.","Brief replication lag during recovery."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Restart a stuck replica","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RESTART REPLICA $TBL\""]}},{"id":"ch.system_sync_replica","title":"SYSTEM SYNC REPLICA <table>","summary":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","description":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","kind":"exec","risk":"medium","side_effects":["Blocks until sync complete.","Replication I/O while catching up."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Wait for replica catch-up","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM SYNC REPLICA $TBL\""]}},{"id":"ch.table_sizes","title":"system.tables uncompressed sizes","summary":"List top 50 tables by uncompressed size.","description":"List top 50 tables by uncompressed size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table sizes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, total_rows, total_bytes, total_bytes_uncompressed FROM system.tables WHERE NOT is_temporary AND engine NOT LIKE 'View%' ORDER BY total_bytes_uncompressed DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.tables_overview","title":"Engine inventory (system.tables)","summary":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","description":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Engine inventory","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, engine, total_rows, total_bytes, parts, active_parts FROM system.tables WHERE database NOT IN ('system','INFORMATION_SCHEMA','information_schema') ORDER BY total_bytes DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.uptime","title":"SELECT version, uptime","summary":"Show server version + uptime.","description":"Show server version + uptime.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Uptime","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT version(), uptime() FORMAT TabSeparatedWithNames\""]}},{"id":"ch.zookeeper_connection","title":"SELECT * FROM system.zookeeper_connection","summary":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","description":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Keeper/ZK connections","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, host, port, index, connected_time, session_uptime_elapsed_seconds, is_expired, keeper_api_version, client_id FROM system.zookeeper_connection FORMAT JSONEachRow\""]}}],"previous_versions":[{"version":"0.2.12","content_hash":"sha256:e6ba21970ce1876375d1095add9a4922fa38a10486d891687de1986a594f15d3","tarball_url":"https://registry.emisar.dev/v1/packs/clickhouse/0.2.12/e6ba21970ce1876375d1095add9a4922fa38a10486d891687de1986a594f15d3/pack.tar.gz","actions":[{"id":"ch.asynchronous_metrics","title":"SELECT * FROM system.asynchronous_metrics","summary":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","description":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Async metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value, description FROM system.asynchronous_metrics ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.backups","title":"SELECT * FROM system.backups","summary":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","description":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Backup/restore status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT id, name, status, substring(error, 1, 300) AS error, start_time, end_time, num_files, total_size FROM system.backups ORDER BY start_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.detached_parts","title":"SELECT * FROM system.detached_parts","summary":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","description":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Detached parts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition_id, name, reason, disk, bytes_on_disk FROM system.detached_parts ORDER BY bytes_on_disk DESC LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.dictionaries","title":"SELECT * FROM system.dictionaries","summary":"List loaded dictionaries with status, element count, source.","description":"List loaded dictionaries with status, element count, source.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Dictionaries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, status, element_count, source FROM system.dictionaries FORMAT JSONEachRow\""]}},{"id":"ch.disks","title":"SELECT * FROM system.disks","summary":"List configured disks with free/used bytes + paths.","description":"List configured disks with free/used bytes + paths.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, path, free_space, total_space, type FROM system.disks FORMAT JSONEachRow\""]}},{"id":"ch.distribution_queue","title":"SELECT * FROM system.distribution_queue","summary":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","description":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Distributed send backlog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_blocked, error_count, data_files, data_compressed_bytes, broken_data_files, last_exception_time, substring(last_exception, 1, 300) AS last_exception FROM system.distribution_queue ORDER BY data_files DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.errors","title":"SELECT * FROM system.errors","summary":"List error codes seen since startup with counts and the last message. Spot error storms.","description":"List error codes seen since startup with counts and the last message. Spot error storms.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recent errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, code, value, last_error_time, substring(last_error_message, 1, 300) AS last_message, remote FROM system.errors WHERE value > 0 ORDER BY last_error_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.keeper_status","title":"List a Keeper/ZooKeeper path (system.zookeeper)","summary":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","description":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"ZooKeeper/Keeper path to list (e.g. /clickhouse/tables).","validation":{"pattern":"^/[A-Za-z0-9_./-]{0,255}$"}}],"examples":[{"title":"List the clickhouse Keeper root","args":{"path":"/clickhouse"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, value, numChildren, ctime, mtime, version, czxid, mzxid FROM system.zookeeper WHERE path = '$ZKPATH' ORDER BY name LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.kill_mutation","title":"Cancel a stuck mutation (KILL MUTATION)","summary":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","description":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","kind":"exec","risk":"critical","side_effects":["The matching mutation is cancelled; its partial work is abandoned.","Targets exactly one mutation — all three identity args are required.","Reversible only by re-issuing the ALTER that created the mutation."],"args":[{"name":"database","type":"string","required":true,"description":"Database of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"table","type":"string","required":true,"description":"Table of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"mutation_id","type":"string","required":true,"description":"mutation_id from ch.stuck_mutations (e.g. mutation_3.txt).","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a stuck mutation","args":{"database":"default","mutation_id":"mutation_3.txt","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL MUTATION WHERE database = '${1}' AND table = '${2}' AND mutation_id = '${3}'\"","emisar","{{ args.database }}","{{ args.table }}","{{ args.mutation_id }}"]}},{"id":"ch.kill_query","title":"KILL QUERY WHERE query_id = '<id>'","summary":"Cancel one running query by ID.","description":"Cancel one running query by ID.","kind":"exec","risk":"high","side_effects":["Targeted query is terminated.","Client receives a cancellation error."],"args":[{"name":"query_id","type":"string","required":true,"description":"Query ID (from system.processes).","validation":{"pattern":"^[a-zA-Z0-9\\-]{1,64}$"}}],"examples":[{"title":"Cancel one query","args":{"query_id":"abc123-def4-5678"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL QUERY WHERE query_id = '$Q' SYNC\""]}},{"id":"ch.merge_queue","title":"SELECT * FROM system.merges","summary":"List in-progress + queued merges.","description":"List in-progress + queued merges.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Active merges","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, elapsed, progress, num_parts, source_part_names, result_part_name, total_size_bytes_compressed, memory_usage FROM system.merges FORMAT JSONEachRow\""]}},{"id":"ch.mutation_queue","title":"SELECT * FROM system.mutations","summary":"List in-progress + pending mutations (ALTER TABLE).","description":"List in-progress + pending mutations (ALTER TABLE).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Pending mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, is_done, parts_to_do, latest_failed_part, latest_fail_reason FROM system.mutations WHERE NOT is_done FORMAT JSONEachRow\""]}},{"id":"ch.optimize_table","title":"OPTIMIZE TABLE FINAL","summary":"Force merge of all parts into one. Heavy disk + CPU.","description":"Force merge of all parts into one. Heavy disk + CPU.","kind":"exec","risk":"high","side_effects":["Background merge runs synchronously; can take minutes-to-hours on large tables.","Temporary doubling of disk space during the merge."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}}],"examples":[{"title":"Optimize table","args":{"database":"default","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"OPTIMIZE TABLE ${1}.${2} FINAL\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"ch.parts_by_partition","title":"Active part count per partition (system.parts)","summary":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","description":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Parts per partition","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition, count() AS parts, sum(rows) AS rows, sum(bytes_on_disk) AS bytes FROM system.parts WHERE active GROUP BY database, table, partition ORDER BY parts DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.parts_summary","title":"SELECT system.parts (by table)","summary":"List active part counts + sizes per table. Use to spot too-many-parts.","description":"List active part counts + sizes per table. Use to spot too-many-parts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top tables by size","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, sum(rows) as rows, sum(bytes_on_disk) as bytes, count() as parts FROM system.parts WHERE active GROUP BY database, table ORDER BY bytes DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.processes","title":"SELECT * FROM system.processes","summary":"List currently-running queries.","description":"List currently-running queries.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT query_id, user, elapsed, memory_usage, read_rows, query FROM system.processes ORDER BY elapsed DESC FORMAT JSONEachRow\""]}},{"id":"ch.query_errors","title":"Failed queries from system.query_log (last hour)","summary":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries.","description":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Failed queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, type, user, query_id, exception_code, substring(exception, 1, 300) AS exception, substring(query, 1, 200) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type IN (3, 4) ORDER BY event_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.reload_config","title":"SYSTEM RELOAD CONFIG","summary":"Re-read config.xml + users.xml without restarting; whatever is now on disk — including changed users and access grants — takes effect on the live server immediately.","description":"Re-read config.xml + users.xml without restarting; whatever is now on disk — including changed users and access grants — takes effect on the live server immediately.","kind":"exec","risk":"high","side_effects":["Config + user definitions reloaded.","Open sessions unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RELOAD CONFIG\""]}},{"id":"ch.replicas_status","title":"SELECT * FROM system.replicas","summary":"Show per-replica state — leader, queue size, log delays, errors.","description":"Show per-replica state — leader, queue size, log delays, errors.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replica health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_leader, is_readonly, future_parts, parts_to_check, queue_size, absolute_delay, log_max_index, log_pointer, total_replicas, active_replicas FROM system.replicas FORMAT JSONEachRow\""]}},{"id":"ch.replication_queue","title":"SELECT * FROM system.replication_queue","summary":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","description":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replication queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, type, create_time, new_part_name, num_tries, is_currently_executing, num_postponed, postpone_reason, last_attempt_time, substring(last_exception, 1, 300) AS last_exception FROM system.replication_queue ORDER BY num_tries DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.slow_queries","title":"system.query_log slowest queries","summary":"List top 50 slowest queries from the last hour.","description":"List top 50 slowest queries from the last hour.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slow queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, query_duration_ms, user, read_rows, memory_usage, query_id, substring(query, 1, 300) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type = 2 ORDER BY query_duration_ms DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.stuck_mutations","title":"Failing mutations (system.mutations)","summary":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","description":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Stuck mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, parts_to_do, latest_failed_part, latest_fail_time, substring(latest_fail_reason, 1, 300) AS fail_reason FROM system.mutations WHERE NOT is_done AND latest_fail_reason != '' ORDER BY create_time ASC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.system_drop_replica","title":"SYSTEM DROP REPLICA <name>","summary":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","description":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","kind":"exec","risk":"critical","side_effects":["Replica metadata deleted from ZK.","Replica cannot rejoin without recreating tables.","Other replicas continue normally."],"args":[{"name":"replica","type":"string","required":true,"description":"Replica name as listed in system.replicas.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Drop dead replica","args":{"replica":"replica-7","table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM DROP REPLICA '$RPL' FROM TABLE $TBL\""]}},{"id":"ch.system_events","title":"SELECT * FROM system.events","summary":"List process-lifetime event counters.","description":"List process-lifetime event counters.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event, value FROM system.events ORDER BY value DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.system_flush_logs","title":"SYSTEM FLUSH LOGS","summary":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","description":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","kind":"exec","risk":"medium","side_effects":["One write to each *_log table.","Brief I/O spike."],"args":[],"examples":[{"title":"Flush log tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM FLUSH LOGS\""]}},{"id":"ch.system_metrics","title":"SELECT * FROM system.metrics","summary":"Show per-metric current values (gauges + counters).","description":"Show per-metric current values (gauges + counters).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value FROM system.metrics WHERE value != 0 ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.system_restart_replica","title":"SYSTEM RESTART REPLICA <table>","summary":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","description":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","kind":"exec","risk":"high","side_effects":["Local replica state reset.","May trigger large data re-fetch from peers.","Brief replication lag during recovery."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Restart a stuck replica","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RESTART REPLICA $TBL\""]}},{"id":"ch.system_sync_replica","title":"SYSTEM SYNC REPLICA <table>","summary":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","description":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","kind":"exec","risk":"medium","side_effects":["Blocks until sync complete.","Replication I/O while catching up."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Wait for replica catch-up","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM SYNC REPLICA $TBL\""]}},{"id":"ch.table_sizes","title":"system.tables uncompressed sizes","summary":"List top 50 tables by uncompressed size.","description":"List top 50 tables by uncompressed size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table sizes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, total_rows, total_bytes, total_bytes_uncompressed FROM system.tables WHERE NOT is_temporary AND engine NOT LIKE 'View%' ORDER BY total_bytes_uncompressed DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.tables_overview","title":"Engine inventory (system.tables)","summary":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","description":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Engine inventory","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, engine, total_rows, total_bytes, parts, active_parts FROM system.tables WHERE database NOT IN ('system','INFORMATION_SCHEMA','information_schema') ORDER BY total_bytes DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.uptime","title":"SELECT version, uptime","summary":"Show server version + uptime.","description":"Show server version + uptime.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Uptime","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT version(), uptime() FORMAT TabSeparatedWithNames\""]}},{"id":"ch.zookeeper_connection","title":"SELECT * FROM system.zookeeper_connection","summary":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","description":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Keeper/ZK connections","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, host, port, index, connected_time, session_uptime_elapsed_seconds, is_expired, keeper_api_version, client_id FROM system.zookeeper_connection FORMAT JSONEachRow\""]}}]},{"version":"0.2.10","content_hash":"sha256:4cdb35f436c0d620efd8086f364e849f6e52f1e29af9eed357fcc67f0d685e38","tarball_url":"https://registry.emisar.dev/v1/packs/clickhouse/0.2.10/4cdb35f436c0d620efd8086f364e849f6e52f1e29af9eed357fcc67f0d685e38/pack.tar.gz","actions":[{"id":"ch.asynchronous_metrics","title":"SELECT * FROM system.asynchronous_metrics","summary":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","description":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Async metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value, description FROM system.asynchronous_metrics ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.backups","title":"SELECT * FROM system.backups","summary":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","description":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Backup/restore status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT id, name, status, substring(error, 1, 300) AS error, start_time, end_time, num_files, total_size FROM system.backups ORDER BY start_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.detached_parts","title":"SELECT * FROM system.detached_parts","summary":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","description":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Detached parts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition_id, name, reason, disk, bytes_on_disk FROM system.detached_parts ORDER BY bytes_on_disk DESC LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.dictionaries","title":"SELECT * FROM system.dictionaries","summary":"List loaded dictionaries with status, element count, source.","description":"List loaded dictionaries with status, element count, source.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Dictionaries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, status, element_count, source FROM system.dictionaries FORMAT JSONEachRow\""]}},{"id":"ch.disks","title":"SELECT * FROM system.disks","summary":"List configured disks with free/used bytes + paths.","description":"List configured disks with free/used bytes + paths.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, path, free_space, total_space, type FROM system.disks FORMAT JSONEachRow\""]}},{"id":"ch.distribution_queue","title":"SELECT * FROM system.distribution_queue","summary":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","description":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Distributed send backlog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_blocked, error_count, data_files, data_compressed_bytes, broken_data_files, last_exception_time, substring(last_exception, 1, 300) AS last_exception FROM system.distribution_queue ORDER BY data_files DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.errors","title":"SELECT * FROM system.errors","summary":"List error codes seen since startup with counts and the last message. Spot error storms.","description":"List error codes seen since startup with counts and the last message. Spot error storms.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recent errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, code, value, last_error_time, substring(last_error_message, 1, 300) AS last_message, remote FROM system.errors WHERE value > 0 ORDER BY last_error_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.keeper_status","title":"List a Keeper/ZooKeeper path (system.zookeeper)","summary":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","description":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"ZooKeeper/Keeper path to list (e.g. /clickhouse/tables).","validation":{"pattern":"^/[A-Za-z0-9_./-]{0,255}$"}}],"examples":[{"title":"List the clickhouse Keeper root","args":{"path":"/clickhouse"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, value, numChildren, ctime, mtime, version, czxid, mzxid FROM system.zookeeper WHERE path = '$ZKPATH' ORDER BY name LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.kill_mutation","title":"Cancel a stuck mutation (KILL MUTATION)","summary":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","description":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","kind":"exec","risk":"critical","side_effects":["The matching mutation is cancelled; its partial work is abandoned.","Targets exactly one mutation — all three identity args are required.","Reversible only by re-issuing the ALTER that created the mutation."],"args":[{"name":"database","type":"string","required":true,"description":"Database of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"table","type":"string","required":true,"description":"Table of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"mutation_id","type":"string","required":true,"description":"mutation_id from ch.stuck_mutations (e.g. mutation_3.txt).","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a stuck mutation","args":{"database":"default","mutation_id":"mutation_3.txt","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL MUTATION WHERE database = '${1}' AND table = '${2}' AND mutation_id = '${3}'\"","emisar","{{ args.database }}","{{ args.table }}","{{ args.mutation_id }}"]}},{"id":"ch.kill_query","title":"KILL QUERY WHERE query_id = '<id>'","summary":"Cancel one running query by ID.","description":"Cancel one running query by ID.","kind":"exec","risk":"high","side_effects":["Targeted query is terminated.","Client receives a cancellation error."],"args":[{"name":"query_id","type":"string","required":true,"description":"Query ID (from system.processes).","validation":{"pattern":"^[a-zA-Z0-9\\-]{1,64}$"}}],"examples":[{"title":"Cancel one query","args":{"query_id":"abc123-def4-5678"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL QUERY WHERE query_id = '$Q' SYNC\""]}},{"id":"ch.merge_queue","title":"SELECT * FROM system.merges","summary":"List in-progress + queued merges.","description":"List in-progress + queued merges.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Active merges","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, elapsed, progress, num_parts, source_part_names, result_part_name, total_size_bytes_compressed, memory_usage FROM system.merges FORMAT JSONEachRow\""]}},{"id":"ch.mutation_queue","title":"SELECT * FROM system.mutations","summary":"List in-progress + pending mutations (ALTER TABLE).","description":"List in-progress + pending mutations (ALTER TABLE).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Pending mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, is_done, parts_to_do, latest_failed_part, latest_fail_reason FROM system.mutations WHERE NOT is_done FORMAT JSONEachRow\""]}},{"id":"ch.optimize_table","title":"OPTIMIZE TABLE FINAL","summary":"Force merge of all parts into one. Heavy disk + CPU.","description":"Force merge of all parts into one. Heavy disk + CPU.","kind":"exec","risk":"high","side_effects":["Background merge runs synchronously; can take minutes-to-hours on large tables.","Temporary doubling of disk space during the merge."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}}],"examples":[{"title":"Optimize table","args":{"database":"default","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"OPTIMIZE TABLE ${1}.${2} FINAL\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"ch.parts_by_partition","title":"Active part count per partition (system.parts)","summary":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","description":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Parts per partition","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition, count() AS parts, sum(rows) AS rows, sum(bytes_on_disk) AS bytes FROM system.parts WHERE active GROUP BY database, table, partition ORDER BY parts DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.parts_summary","title":"SELECT system.parts (by table)","summary":"List active part counts + sizes per table. Use to spot too-many-parts.","description":"List active part counts + sizes per table. Use to spot too-many-parts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top tables by size","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, sum(rows) as rows, sum(bytes_on_disk) as bytes, count() as parts FROM system.parts WHERE active GROUP BY database, table ORDER BY bytes DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.processes","title":"SELECT * FROM system.processes","summary":"List currently-running queries.","description":"List currently-running queries.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT query_id, user, elapsed, memory_usage, read_rows, query FROM system.processes ORDER BY elapsed DESC FORMAT JSONEachRow\""]}},{"id":"ch.query_errors","title":"Failed queries from system.query_log (last hour)","summary":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries.","description":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Failed queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, type, user, query_id, exception_code, substring(exception, 1, 300) AS exception, substring(query, 1, 200) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type IN (3, 4) ORDER BY event_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.reload_config","title":"SYSTEM RELOAD CONFIG","summary":"Re-read config.xml + users.xml without restarting; whatever is now on disk — including changed users and access grants — takes effect on the live server immediately.","description":"Re-read config.xml + users.xml without restarting; whatever is now on disk — including changed users and access grants — takes effect on the live server immediately.","kind":"exec","risk":"high","side_effects":["Config + user definitions reloaded.","Open sessions unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RELOAD CONFIG\""]}},{"id":"ch.replicas_status","title":"SELECT * FROM system.replicas","summary":"Show per-replica state — leader, queue size, log delays, errors.","description":"Show per-replica state — leader, queue size, log delays, errors.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replica health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_leader, is_readonly, future_parts, parts_to_check, queue_size, absolute_delay, log_max_index, log_pointer, total_replicas, active_replicas FROM system.replicas FORMAT JSONEachRow\""]}},{"id":"ch.replication_queue","title":"SELECT * FROM system.replication_queue","summary":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","description":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replication queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, type, create_time, new_part_name, num_tries, is_currently_executing, num_postponed, postpone_reason, last_attempt_time, substring(last_exception, 1, 300) AS last_exception FROM system.replication_queue ORDER BY num_tries DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.slow_queries","title":"system.query_log slowest queries","summary":"List top 50 slowest queries from the last hour.","description":"List top 50 slowest queries from the last hour.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slow queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, query_duration_ms, user, read_rows, memory_usage, query_id, substring(query, 1, 300) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type = 2 ORDER BY query_duration_ms DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.stuck_mutations","title":"Failing mutations (system.mutations)","summary":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","description":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Stuck mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, parts_to_do, latest_failed_part, latest_fail_time, substring(latest_fail_reason, 1, 300) AS fail_reason FROM system.mutations WHERE NOT is_done AND latest_fail_reason != '' ORDER BY create_time ASC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.system_drop_replica","title":"SYSTEM DROP REPLICA <name>","summary":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","description":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","kind":"exec","risk":"critical","side_effects":["Replica metadata deleted from ZK.","Replica cannot rejoin without recreating tables.","Other replicas continue normally."],"args":[{"name":"replica","type":"string","required":true,"description":"Replica name as listed in system.replicas.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Drop dead replica","args":{"replica":"replica-7","table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM DROP REPLICA '$RPL' FROM TABLE $TBL\""]}},{"id":"ch.system_events","title":"SELECT * FROM system.events","summary":"List process-lifetime event counters.","description":"List process-lifetime event counters.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event, value FROM system.events ORDER BY value DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.system_flush_logs","title":"SYSTEM FLUSH LOGS","summary":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","description":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","kind":"exec","risk":"medium","side_effects":["One write to each *_log table.","Brief I/O spike."],"args":[],"examples":[{"title":"Flush log tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM FLUSH LOGS\""]}},{"id":"ch.system_metrics","title":"SELECT * FROM system.metrics","summary":"Show per-metric current values (gauges + counters).","description":"Show per-metric current values (gauges + counters).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value FROM system.metrics WHERE value != 0 ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.system_restart_replica","title":"SYSTEM RESTART REPLICA <table>","summary":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","description":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","kind":"exec","risk":"high","side_effects":["Local replica state reset.","May trigger large data re-fetch from peers.","Brief replication lag during recovery."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Restart a stuck replica","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RESTART REPLICA $TBL\""]}},{"id":"ch.system_sync_replica","title":"SYSTEM SYNC REPLICA <table>","summary":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","description":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","kind":"exec","risk":"medium","side_effects":["Blocks until sync complete.","Replication I/O while catching up."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Wait for replica catch-up","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM SYNC REPLICA $TBL\""]}},{"id":"ch.table_sizes","title":"system.tables uncompressed sizes","summary":"List top 50 tables by uncompressed size.","description":"List top 50 tables by uncompressed size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table sizes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, total_rows, total_bytes, total_bytes_uncompressed FROM system.tables WHERE NOT is_temporary AND engine NOT LIKE 'View%' ORDER BY total_bytes_uncompressed DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.tables_overview","title":"Engine inventory (system.tables)","summary":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","description":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Engine inventory","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, engine, total_rows, total_bytes, parts, active_parts FROM system.tables WHERE database NOT IN ('system','INFORMATION_SCHEMA','information_schema') ORDER BY total_bytes DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.uptime","title":"SELECT version, uptime","summary":"Show server version + uptime.","description":"Show server version + uptime.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Uptime","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT version(), uptime() FORMAT TabSeparatedWithNames\""]}},{"id":"ch.zookeeper_connection","title":"SELECT * FROM system.zookeeper_connection","summary":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","description":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Keeper/ZK connections","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, host, port, index, connected_time, session_uptime_elapsed_seconds, is_expired, keeper_api_version, client_id FROM system.zookeeper_connection FORMAT JSONEachRow\""]}}]},{"version":"0.2.8","content_hash":"sha256:102855cbb046d9b72e7297e749c39d0f787dbc6fd237511c71a59a46eef366a9","tarball_url":"https://registry.emisar.dev/v1/packs/clickhouse/0.2.8/102855cbb046d9b72e7297e749c39d0f787dbc6fd237511c71a59a46eef366a9/pack.tar.gz","actions":[{"id":"ch.asynchronous_metrics","title":"SELECT * FROM system.asynchronous_metrics","summary":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","description":"Show periodically-computed metrics — replica lag (ReplicasMaxAbsoluteDelay), max parts per partition, filesystem and memory. The async counterpart to system.metrics.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Async metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value, description FROM system.asynchronous_metrics ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.backups","title":"SELECT * FROM system.backups","summary":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","description":"List BACKUP/RESTORE operations since the last server start with status and error. Non-persistent across restarts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Backup/restore status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT id, name, status, substring(error, 1, 300) AS error, start_time, end_time, num_files, total_size FROM system.backups ORDER BY start_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.detached_parts","title":"SELECT * FROM system.detached_parts","summary":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","description":"List parts ClickHouse detached and will not auto-attach (corruption, manual detach, broken), each with a reason. Empty is healthy.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Detached parts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition_id, name, reason, disk, bytes_on_disk FROM system.detached_parts ORDER BY bytes_on_disk DESC LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.dictionaries","title":"SELECT * FROM system.dictionaries","summary":"List loaded dictionaries with status, element count, source.","description":"List loaded dictionaries with status, element count, source.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Dictionaries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, status, element_count, source FROM system.dictionaries FORMAT JSONEachRow\""]}},{"id":"ch.disks","title":"SELECT * FROM system.disks","summary":"List configured disks with free/used bytes + paths.","description":"List configured disks with free/used bytes + paths.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, path, free_space, total_space, type FROM system.disks FORMAT JSONEachRow\""]}},{"id":"ch.distribution_queue","title":"SELECT * FROM system.distribution_queue","summary":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","description":"Show distributed-table async send backlog — pending files, errors, blocked sends. Spot a Distributed table not flushing to shards.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Distributed send backlog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_blocked, error_count, data_files, data_compressed_bytes, broken_data_files, last_exception_time, substring(last_exception, 1, 300) AS last_exception FROM system.distribution_queue ORDER BY data_files DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.errors","title":"SELECT * FROM system.errors","summary":"List error codes seen since startup with counts and the last message. Spot error storms.","description":"List error codes seen since startup with counts and the last message. Spot error storms.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recent errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, code, value, last_error_time, substring(last_error_message, 1, 300) AS last_message, remote FROM system.errors WHERE value > 0 ORDER BY last_error_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.keeper_status","title":"List a Keeper/ZooKeeper path (system.zookeeper)","summary":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","description":"List child nodes and metadata under a Keeper/ZooKeeper path. system.zookeeper requires a path filter, so the path arg is mandatory.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"ZooKeeper/Keeper path to list (e.g. /clickhouse/tables).","validation":{"pattern":"^/[A-Za-z0-9_./-]{0,255}$"}}],"examples":[{"title":"List the clickhouse Keeper root","args":{"path":"/clickhouse"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, value, numChildren, ctime, mtime, version, czxid, mzxid FROM system.zookeeper WHERE path = '$ZKPATH' ORDER BY name LIMIT 500 FORMAT JSONEachRow\""]}},{"id":"ch.kill_mutation","title":"Cancel a stuck mutation (KILL MUTATION)","summary":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","description":"Cancel one ClickHouse mutation by its (database, table, mutation_id) — KILL MUTATION WHERE …. Use to stop a mutation wedged on a failure (see ch.stuck_mutations) so the table's merges and inserts can proceed. Destructive — the mutation is abandoned mid-flight — so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH mutations are permitted is a portal policy decision.","kind":"exec","risk":"critical","side_effects":["The matching mutation is cancelled; its partial work is abandoned.","Targets exactly one mutation — all three identity args are required.","Reversible only by re-issuing the ALTER that created the mutation."],"args":[{"name":"database","type":"string","required":true,"description":"Database of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"table","type":"string","required":true,"description":"Table of the mutation (from ch.stuck_mutations).","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_]{0,127}$","max_length":128}},{"name":"mutation_id","type":"string","required":true,"description":"mutation_id from ch.stuck_mutations (e.g. mutation_3.txt).","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a stuck mutation","args":{"database":"default","mutation_id":"mutation_3.txt","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL MUTATION WHERE database = '${1}' AND table = '${2}' AND mutation_id = '${3}'\"","emisar","{{ args.database }}","{{ args.table }}","{{ args.mutation_id }}"]}},{"id":"ch.kill_query","title":"KILL QUERY WHERE query_id = '<id>'","summary":"Cancels one running query by ID.","description":"Cancels one running query by ID.","kind":"exec","risk":"high","side_effects":["Targeted query is terminated.","Client receives a cancellation error."],"args":[{"name":"query_id","type":"string","required":true,"description":"Query ID (from system.processes).","validation":{"pattern":"^[a-zA-Z0-9\\-]{1,64}$"}}],"examples":[{"title":"Cancel one query","args":{"query_id":"abc123-def4-5678"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"KILL QUERY WHERE query_id = '$Q' SYNC\""]}},{"id":"ch.merge_queue","title":"SELECT * FROM system.merges","summary":"List in-progress + queued merges.","description":"List in-progress + queued merges.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Active merges","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, elapsed, progress, num_parts, source_part_names, result_part_name, total_size_bytes_compressed, memory_usage FROM system.merges FORMAT JSONEachRow\""]}},{"id":"ch.mutation_queue","title":"SELECT * FROM system.mutations","summary":"List in-progress + pending mutations (ALTER TABLE).","description":"List in-progress + pending mutations (ALTER TABLE).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Pending mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, is_done, parts_to_do, latest_failed_part, latest_fail_reason FROM system.mutations WHERE NOT is_done FORMAT JSONEachRow\""]}},{"id":"ch.optimize_table","title":"OPTIMIZE TABLE FINAL","summary":"Forces merge of all parts into one. Heavy disk + CPU.","description":"Forces merge of all parts into one. Heavy disk + CPU.","kind":"exec","risk":"high","side_effects":["Background merge runs synchronously; can take minutes-to-hours on large tables.","Temporary doubling of disk space during the merge."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,128}$"}}],"examples":[{"title":"Optimize table","args":{"database":"default","table":"events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"OPTIMIZE TABLE ${1}.${2} FINAL\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"ch.parts_by_partition","title":"Active part count per partition (system.parts)","summary":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","description":"List active parts grouped by partition, top offenders first. Where you actually diagnose too-many-parts / merge backlog (parts_summary is table-level only).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Parts per partition","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, partition, count() AS parts, sum(rows) AS rows, sum(bytes_on_disk) AS bytes FROM system.parts WHERE active GROUP BY database, table, partition ORDER BY parts DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.parts_summary","title":"SELECT system.parts (by table)","summary":"List active part counts + sizes per table. Use to spot too-many-parts.","description":"List active part counts + sizes per table. Use to spot too-many-parts.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top tables by size","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, sum(rows) as rows, sum(bytes_on_disk) as bytes, count() as parts FROM system.parts WHERE active GROUP BY database, table ORDER BY bytes DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.processes","title":"SELECT * FROM system.processes","summary":"List currently-running queries.","description":"List currently-running queries.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT query_id, user, elapsed, memory_usage, read_rows, query FROM system.processes ORDER BY elapsed DESC FORMAT JSONEachRow\""]}},{"id":"ch.query_errors","title":"Failed queries from system.query_log (last hour)","summary":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries.","description":"List queries that failed in the last hour (exception types 3 and 4) with code, message, and query. The error counterpart to slow_queries.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Failed queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, type, user, query_id, exception_code, substring(exception, 1, 300) AS exception, substring(query, 1, 200) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type IN (3, 4) ORDER BY event_time DESC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.reload_config","title":"SYSTEM RELOAD CONFIG","summary":"Re-reads config.xml + users.xml without restarting.","description":"Re-reads config.xml + users.xml without restarting.","kind":"exec","risk":"high","side_effects":["Config + user definitions reloaded.","Open sessions unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RELOAD CONFIG\""]}},{"id":"ch.replicas_status","title":"SELECT * FROM system.replicas","summary":"Show per-replica state — leader, queue size, log delays, errors.","description":"Show per-replica state — leader, queue size, log delays, errors.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replica health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, is_leader, is_readonly, future_parts, parts_to_check, queue_size, absolute_delay, log_max_index, log_pointer, total_replicas, active_replicas FROM system.replicas FORMAT JSONEachRow\""]}},{"id":"ch.replication_queue","title":"SELECT * FROM system.replication_queue","summary":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","description":"Show per-task replication queue — retries, postpones, last exception. Spot stuck fetches/merges (distinct from per-replica state).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Replication queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, type, create_time, new_part_name, num_tries, is_currently_executing, num_postponed, postpone_reason, last_attempt_time, substring(last_exception, 1, 300) AS last_exception FROM system.replication_queue ORDER BY num_tries DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.slow_queries","title":"system.query_log slowest queries","summary":"List top 50 slowest queries from the last hour.","description":"List top 50 slowest queries from the last hour.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slow queries (1h)","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event_time, query_duration_ms, user, read_rows, memory_usage, query_id, substring(query, 1, 300) AS q FROM system.query_log WHERE event_time > now() - INTERVAL 1 HOUR AND type = 2 ORDER BY query_duration_ms DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.stuck_mutations","title":"Failing mutations (system.mutations)","summary":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","description":"List mutations stuck on a failure (latest_fail_reason set), with the failed part and reason. Narrower than the full mutation queue — surfaces only what is actively failing.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Stuck mutations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, table, mutation_id, command, create_time, parts_to_do, latest_failed_part, latest_fail_time, substring(latest_fail_reason, 1, 300) AS fail_reason FROM system.mutations WHERE NOT is_done AND latest_fail_reason != '' ORDER BY create_time ASC LIMIT 100 FORMAT JSONEachRow\""]}},{"id":"ch.system_drop_replica","title":"SYSTEM DROP REPLICA <name>","summary":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","description":"Remove a replica's metadata from ZooKeeper for one table. Use only for an already-dead replica that is never coming back. The replica cannot rejoin without recreating its tables. Wrong replica name destroys a healthy cluster member's metadata.","kind":"exec","risk":"critical","side_effects":["Replica metadata deleted from ZK.","Replica cannot rejoin without recreating tables.","Other replicas continue normally."],"args":[{"name":"replica","type":"string","required":true,"description":"Replica name as listed in system.replicas.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-]{1,128}$"}},{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Drop dead replica","args":{"replica":"replica-7","table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM DROP REPLICA '$RPL' FROM TABLE $TBL\""]}},{"id":"ch.system_events","title":"SELECT * FROM system.events","summary":"List process-lifetime event counters.","description":"List process-lifetime event counters.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Top events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT event, value FROM system.events ORDER BY value DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.system_flush_logs","title":"SYSTEM FLUSH LOGS","summary":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","description":"Force write buffered system.*log tables to disk. Use before querying very recent activity from query_log, part_log, etc.","kind":"exec","risk":"medium","side_effects":["One write to each *_log table.","Brief I/O spike."],"args":[],"examples":[{"title":"Flush log tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM FLUSH LOGS\""]}},{"id":"ch.system_metrics","title":"SELECT * FROM system.metrics","summary":"Show per-metric current values (gauges + counters).","description":"Show per-metric current values (gauges + counters).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT metric, value FROM system.metrics WHERE value != 0 ORDER BY metric FORMAT JSONEachRow\""]}},{"id":"ch.system_restart_replica","title":"SYSTEM RESTART REPLICA <table>","summary":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","description":"Reinitialize the local replication state for one table. Useful when the replica is stuck or its ZooKeeper state diverged. Heavy — may re-fetch many parts.","kind":"exec","risk":"high","side_effects":["Local replica state reset.","May trigger large data re-fetch from peers.","Brief replication lag during recovery."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Restart a stuck replica","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM RESTART REPLICA $TBL\""]}},{"id":"ch.system_sync_replica","title":"SYSTEM SYNC REPLICA <table>","summary":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","description":"Wait for the local replica to catch up with all peers. Returns when in sync. Use to confirm replication caught up before doing reads from this replica.","kind":"exec","risk":"medium","side_effects":["Blocks until sync complete.","Replication I/O while catching up."],"args":[{"name":"table","type":"string","required":true,"description":"Database.table (qualified).","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}\\.[a-zA-Z0-9_]{1,128}$"}}],"examples":[{"title":"Wait for replica catch-up","args":{"table":"analytics.events"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SYSTEM SYNC REPLICA $TBL\""]}},{"id":"ch.table_sizes","title":"system.tables uncompressed sizes","summary":"List top 50 tables by uncompressed size.","description":"List top 50 tables by uncompressed size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table sizes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, total_rows, total_bytes, total_bytes_uncompressed FROM system.tables WHERE NOT is_temporary AND engine NOT LIKE 'View%' ORDER BY total_bytes_uncompressed DESC LIMIT 50 FORMAT JSONEachRow\""]}},{"id":"ch.tables_overview","title":"Engine inventory (system.tables)","summary":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","description":"List all non-system tables with engine, row/byte totals, and part counts. Engine inventory + fleet shape.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Engine inventory","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT database, name, engine, total_rows, total_bytes, parts, active_parts FROM system.tables WHERE database NOT IN ('system','INFORMATION_SCHEMA','information_schema') ORDER BY total_bytes DESC LIMIT 200 FORMAT JSONEachRow\""]}},{"id":"ch.uptime","title":"SELECT version, uptime","summary":"Show server version + uptime.","description":"Show server version + uptime.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Uptime","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT version(), uptime() FORMAT TabSeparatedWithNames\""]}},{"id":"ch.zookeeper_connection","title":"SELECT * FROM system.zookeeper_connection","summary":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","description":"List active Keeper/ZooKeeper connections — host, session age, expiry, API version. Empty on a non-replicated single node.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Keeper/ZK connections","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","CLICKHOUSE_PASSWORD=\"$CH_PASSWORD\" clickhouse-client --host \"${CH_HOST:-localhost}\" --user \"${CH_USER:-default}\" --query \"SELECT name, host, port, index, connected_time, session_uptime_elapsed_seconds, is_expired, keeper_api_version, client_id FROM system.zookeeper_connection FORMAT JSONEachRow\""]}}]}]},{"id":"cloud-init","name":"cloud-init operations","version":"0.1.15","description":"cloud-init introspection + boot diagnostics + stage re-runs. Use when an EC2/GCE/Azure VM finishes booting but the workload didn't come up the way it should: check overall status, blame slow modules, dump user-data / cloud-config / vendor-data as the instance actually saw them, tail the cloud-init logs, and (with operator approval) re-run individual modules or the full init pipeline.","vendor":"emisar","homepage":"https://emisar.dev/packs/cloud-init","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/cloud-init","content_hash":"sha256:1b95abef58d435b25559b4e76a7ec089861cb7efceb445f226c2c53b5c035933","tarball_url":"https://registry.emisar.dev/v1/packs/cloud-init/0.1.15/1b95abef58d435b25559b4e76a7ec089861cb7efceb445f226c2c53b5c035933/pack.tar.gz","requires":{"os":["linux"],"binaries":["cloud-init"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Reads the local runner host's cloud-init status, logs, and results — no credentials needed.","notes":["Status, version, schema validation, and instance-id reads work without elevated host access."],"host_access":[{"actions":["cloud-init.analyze_show","cloud-init.analyze_blame","cloud-init.analyze_dump","cloud-init.userdata_dump","cloud-init.cloud_config_dump","cloud-init.vendor_data_dump","cloud-init.log_tail","cloud-init.output_log_tail","cloud-init.journal_tail","cloud-init.collect_logs","cloud-init.modules_config","cloud-init.modules_final","cloud-init.single_module","cloud-init.init_local","cloud-init.init","cloud-init.clean_logs","cloud-init.clean"],"requirement":"Read protected cloud-init state and logs, or rerun and clean boot stages, as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-cloud-init-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Cloud-init reads may expose raw user-data secrets, and mutators can reapply provisioning or erase instance state."}]}],"verify":"cloud-init.status"},"actions":[{"id":"cloud-init.analyze_blame","title":"cloud-init analyze blame","summary":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","description":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Slowest modules","args":{}}],"search_terms":["slow boot","slow provisioning"],"command":{"binary":"cloud-init","argv":["analyze","blame"]}},{"id":"cloud-init.analyze_dump","title":"cloud-init analyze dump","summary":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","description":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Raw boot events JSON","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","dump"]}},{"id":"cloud-init.analyze_show","title":"cloud-init analyze show","summary":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","description":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Boot timeline","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","show"]}},{"id":"cloud-init.clean","title":"cloud-init clean","summary":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","description":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","kind":"exec","risk":"critical","side_effects":["All cloud-init state cleared.","Next boot re-runs init-local, init, config, final.","Any post-cloud-init changes that cloud-init didn't make will be left alone, BUT cloud-init modules will treat their state as fresh and may overwrite.","With `--seed`, also wipes /var/lib/cloud/seed/."],"args":[{"name":"seed","type":"boolean","required":false,"default":false,"description":"Also wipe the seed dir (NoCloud datasource)."}],"examples":[{"title":"Reset cloud-init state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.seed }}' = 'true' ]; then cloud-init clean --seed; else cloud-init clean; fi"]}},{"id":"cloud-init.clean_logs","title":"cloud-init clean --logs","summary":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","description":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","kind":"exec","risk":"medium","side_effects":["/var/log/cloud-init.log + /var/log/cloud-init-output.log truncated.","instance-id + module-run state preserved (use `clean` to also reset those)."],"args":[],"examples":[{"title":"Clear logs only","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["clean","--logs"]}},{"id":"cloud-init.cloud_config_dump","title":"cat /var/lib/cloud/instance/cloud-config.txt","summary":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes the merged cloud-config (may include secrets)."],"args":[],"examples":[{"title":"Effective cloud-config","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/cloud-config.txt"]}},{"id":"cloud-init.collect_logs","title":"cloud-init collect-logs","summary":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","description":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","kind":"exec","risk":"medium","side_effects":["Writes /tmp/cloud-init.tar.gz (overwrites if present).","May briefly stress disk + tar throughput."],"args":[],"examples":[{"title":"Collect support bundle","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["collect-logs"]}},{"id":"cloud-init.init","title":"cloud-init init","summary":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","description":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","kind":"exec","risk":"high","side_effects":["Datasource is re-fetched.","user-data / vendor-data files refreshed.","Subsequent stages (config, final) NOT re-run unless invoked."],"args":[],"examples":[{"title":"Re-run init stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init"]}},{"id":"cloud-init.init_local","title":"cloud-init init --local","summary":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","description":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","kind":"exec","risk":"high","side_effects":["Datasource detection re-runs.","Network may briefly reconfigure.","/var/lib/cloud/instance/ state files refreshed."],"args":[],"examples":[{"title":"Re-run init-local","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init","--local"]}},{"id":"cloud-init.instance_id","title":"cat /var/lib/cloud/data/instance-id","summary":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","description":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","kind":"exec","risk":"low","side_effects":["Reads one file.","No mutation."],"args":[],"examples":[{"title":"Instance id","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/data/instance-id"]}},{"id":"cloud-init.journal_tail","title":"journalctl -u cloud-init -n <lines>","summary":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","description":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","kind":"exec","risk":"medium","side_effects":["Reads the systemd journal.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 journal lines","args":{}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","cloud-init","-u","cloud-init-local","-u","cloud-config","-u","cloud-final","-n","{{ args.lines }}","--no-pager"]}},{"id":"cloud-init.log_tail","title":"tail /var/log/cloud-init.log","summary":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","description":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","kind":"exec","risk":"medium","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init.log"]}},{"id":"cloud-init.modules_config","title":"cloud-init modules --mode=config","summary":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","description":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","kind":"exec","risk":"high","side_effects":["Every module in the config stage re-runs.","System packages may install/update.","User accounts, ssh keys, apt sources may change.","Idempotent in design — but only as idempotent as the modules in your config."],"args":[],"examples":[{"title":"Re-apply config stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=config"]}},{"id":"cloud-init.modules_final","title":"cloud-init modules --mode=final","summary":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","description":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","kind":"exec","risk":"high","side_effects":["Every module in the final stage re-runs.","User scripts under /var/lib/cloud/scripts/per-once and per-boot may execute.","power-state-change may reboot the host."],"args":[],"examples":[{"title":"Re-apply final stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=final"]}},{"id":"cloud-init.output_log_tail","title":"tail /var/log/cloud-init-output.log","summary":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","description":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","kind":"exec","risk":"medium","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines of command output","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init-output.log"]}},{"id":"cloud-init.query_metadata","title":"cloud-init query <key>","summary":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only."],"args":[{"name":"key","type":"string","required":false,"default":"--all","description":"Metadata key, or \"--all\" for everything.","validation":{"pattern":"^(--all|[a-zA-Z0-9_./\\-]{1,128})$"}}],"examples":[{"title":"All metadata","args":{}},{"title":"Instance id only","args":{"key":"instance-id"}},{"title":"Cloud-config user-data","args":{"key":"userdata"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["query","{{ args.key }}"]}},{"id":"cloud-init.schema_validate","title":"cloud-init schema --system","summary":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","description":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Validate effective config","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["schema","--system"]}},{"id":"cloud-init.single_module","title":"cloud-init single --name=<module>","summary":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","description":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","kind":"exec","risk":"high","side_effects":["One module executes.","Behavior depends on the module — could mutate users, ssh keys, hostname, packages, runcmd, etc."],"args":[{"name":"module","type":"string","required":true,"description":"Module name (e.g., users_groups, ssh, set_hostname).","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"frequency","type":"string","required":false,"default":"always","description":"When to consider the module previously run.","validation":{"enum":["always","instance","once"]}}],"examples":[{"title":"Re-run users-groups","args":{"module":"users_groups"}},{"title":"Re-run ssh module","args":{"module":"ssh"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["single","--name={{ args.module }}","--frequency={{ args.frequency }}"]}},{"id":"cloud-init.status","title":"cloud-init status","summary":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","description":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Current status","args":{}}],"search_terms":["provisioning"],"command":{"binary":"cloud-init","argv":["status"]}},{"id":"cloud-init.status_long","title":"cloud-init status --long [--wait]","summary":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","description":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","kind":"exec","risk":"low","side_effects":["One CLI call (may block up to timeout if block=true).","Read-only."],"args":[{"name":"block","type":"boolean","required":false,"default":false,"description":"Block until cloud-init exits the running state (passes --wait)."}],"examples":[{"title":"Detailed status","args":{}},{"title":"Wait for boot","args":{"block":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.block }}' = 'true' ]; then cloud-init status --long --wait; else cloud-init status --long; fi"]}},{"id":"cloud-init.userdata_dump","title":"cat /var/lib/cloud/instance/user-data.txt","summary":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw user-data (may include secrets)."],"args":[],"examples":[{"title":"Raw user-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/user-data.txt"]}},{"id":"cloud-init.vendor_data_dump","title":"cat /var/lib/cloud/instance/vendor-data.txt","summary":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw vendor-data (may include secrets)."],"args":[],"examples":[{"title":"Vendor-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/vendor-data.txt"]}},{"id":"cloud-init.version","title":"cloud-init --version","summary":"Show the build + version string for the cloud-init on this host.","description":"Show the build + version string for the cloud-init on this host.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["--version"]}}],"previous_versions":[{"version":"0.1.13","content_hash":"sha256:fcc1b21a5335f88f74c4fbe5278c2f6d3cce16c6e97678ef5cf75ac1c00a1971","tarball_url":"https://registry.emisar.dev/v1/packs/cloud-init/0.1.13/fcc1b21a5335f88f74c4fbe5278c2f6d3cce16c6e97678ef5cf75ac1c00a1971/pack.tar.gz","actions":[{"id":"cloud-init.analyze_blame","title":"cloud-init analyze blame","summary":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","description":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Slowest modules","args":{}}],"search_terms":["slow boot","slow provisioning"],"command":{"binary":"cloud-init","argv":["analyze","blame"]}},{"id":"cloud-init.analyze_dump","title":"cloud-init analyze dump","summary":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","description":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Raw boot events JSON","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","dump"]}},{"id":"cloud-init.analyze_show","title":"cloud-init analyze show","summary":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","description":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Boot timeline","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","show"]}},{"id":"cloud-init.clean","title":"cloud-init clean","summary":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","description":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","kind":"exec","risk":"critical","side_effects":["All cloud-init state cleared.","Next boot re-runs init-local, init, config, final.","Any post-cloud-init changes that cloud-init didn't make will be left alone, BUT cloud-init modules will treat their state as fresh and may overwrite.","With `--seed`, also wipes /var/lib/cloud/seed/."],"args":[{"name":"seed","type":"boolean","required":false,"default":false,"description":"Also wipe the seed dir (NoCloud datasource)."}],"examples":[{"title":"Reset cloud-init state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.seed }}' = 'true' ]; then cloud-init clean --seed; else cloud-init clean; fi"]}},{"id":"cloud-init.clean_logs","title":"cloud-init clean --logs","summary":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","description":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","kind":"exec","risk":"medium","side_effects":["/var/log/cloud-init.log + /var/log/cloud-init-output.log truncated.","instance-id + module-run state preserved (use `clean` to also reset those)."],"args":[],"examples":[{"title":"Clear logs only","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["clean","--logs"]}},{"id":"cloud-init.cloud_config_dump","title":"cat /var/lib/cloud/instance/cloud-config.txt","summary":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes the merged cloud-config (may include secrets)."],"args":[],"examples":[{"title":"Effective cloud-config","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/cloud-config.txt"]}},{"id":"cloud-init.collect_logs","title":"cloud-init collect-logs","summary":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","description":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","kind":"exec","risk":"medium","side_effects":["Writes /tmp/cloud-init.tar.gz (overwrites if present).","May briefly stress disk + tar throughput."],"args":[],"examples":[{"title":"Collect support bundle","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["collect-logs"]}},{"id":"cloud-init.init","title":"cloud-init init","summary":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","description":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","kind":"exec","risk":"high","side_effects":["Datasource is re-fetched.","user-data / vendor-data files refreshed.","Subsequent stages (config, final) NOT re-run unless invoked."],"args":[],"examples":[{"title":"Re-run init stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init"]}},{"id":"cloud-init.init_local","title":"cloud-init init --local","summary":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","description":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","kind":"exec","risk":"high","side_effects":["Datasource detection re-runs.","Network may briefly reconfigure.","/var/lib/cloud/instance/ state files refreshed."],"args":[],"examples":[{"title":"Re-run init-local","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init","--local"]}},{"id":"cloud-init.instance_id","title":"cat /var/lib/cloud/data/instance-id","summary":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","description":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","kind":"exec","risk":"low","side_effects":["Reads one file.","No mutation."],"args":[],"examples":[{"title":"Instance id","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/data/instance-id"]}},{"id":"cloud-init.journal_tail","title":"journalctl -u cloud-init -n <lines>","summary":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","description":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","kind":"exec","risk":"low","side_effects":["Reads the systemd journal.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 journal lines","args":{}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","cloud-init","-u","cloud-init-local","-u","cloud-config","-u","cloud-final","-n","{{ args.lines }}","--no-pager"]}},{"id":"cloud-init.log_tail","title":"tail /var/log/cloud-init.log","summary":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","description":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","kind":"exec","risk":"low","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init.log"]}},{"id":"cloud-init.modules_config","title":"cloud-init modules --mode=config","summary":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","description":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","kind":"exec","risk":"high","side_effects":["Every module in the config stage re-runs.","System packages may install/update.","User accounts, ssh keys, apt sources may change.","Idempotent in design — but only as idempotent as the modules in your config."],"args":[],"examples":[{"title":"Re-apply config stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=config"]}},{"id":"cloud-init.modules_final","title":"cloud-init modules --mode=final","summary":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","description":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","kind":"exec","risk":"high","side_effects":["Every module in the final stage re-runs.","User scripts under /var/lib/cloud/scripts/per-once and per-boot may execute.","power-state-change may reboot the host."],"args":[],"examples":[{"title":"Re-apply final stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=final"]}},{"id":"cloud-init.output_log_tail","title":"tail /var/log/cloud-init-output.log","summary":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","description":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","kind":"exec","risk":"low","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines of command output","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init-output.log"]}},{"id":"cloud-init.query_metadata","title":"cloud-init query <key>","summary":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only."],"args":[{"name":"key","type":"string","required":false,"default":"--all","description":"Metadata key, or \"--all\" for everything.","validation":{"pattern":"^(--all|[a-zA-Z0-9_./\\-]{1,128})$"}}],"examples":[{"title":"All metadata","args":{}},{"title":"Instance id only","args":{"key":"instance-id"}},{"title":"Cloud-config user-data","args":{"key":"userdata"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["query","{{ args.key }}"]}},{"id":"cloud-init.schema_validate","title":"cloud-init schema --system","summary":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","description":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Validate effective config","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["schema","--system"]}},{"id":"cloud-init.single_module","title":"cloud-init single --name=<module>","summary":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","description":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","kind":"exec","risk":"high","side_effects":["One module executes.","Behavior depends on the module — could mutate users, ssh keys, hostname, packages, runcmd, etc."],"args":[{"name":"module","type":"string","required":true,"description":"Module name (e.g., users_groups, ssh, set_hostname).","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"frequency","type":"string","required":false,"default":"always","description":"When to consider the module previously run.","validation":{"enum":["always","instance","once"]}}],"examples":[{"title":"Re-run users-groups","args":{"module":"users_groups"}},{"title":"Re-run ssh module","args":{"module":"ssh"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["single","--name={{ args.module }}","--frequency={{ args.frequency }}"]}},{"id":"cloud-init.status","title":"cloud-init status","summary":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","description":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Current status","args":{}}],"search_terms":["provisioning"],"command":{"binary":"cloud-init","argv":["status"]}},{"id":"cloud-init.status_long","title":"cloud-init status --long [--wait]","summary":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","description":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","kind":"exec","risk":"low","side_effects":["One CLI call (may block up to timeout if block=true).","Read-only."],"args":[{"name":"block","type":"boolean","required":false,"default":false,"description":"Block until cloud-init exits the running state (passes --wait)."}],"examples":[{"title":"Detailed status","args":{}},{"title":"Wait for boot","args":{"block":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.block }}' = 'true' ]; then cloud-init status --long --wait; else cloud-init status --long; fi"]}},{"id":"cloud-init.userdata_dump","title":"cat /var/lib/cloud/instance/user-data.txt","summary":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw user-data (may include secrets)."],"args":[],"examples":[{"title":"Raw user-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/user-data.txt"]}},{"id":"cloud-init.vendor_data_dump","title":"cat /var/lib/cloud/instance/vendor-data.txt","summary":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw vendor-data (may include secrets)."],"args":[],"examples":[{"title":"Vendor-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/vendor-data.txt"]}},{"id":"cloud-init.version","title":"cloud-init --version","summary":"Show the build + version string for the cloud-init on this host.","description":"Show the build + version string for the cloud-init on this host.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["--version"]}}]},{"version":"0.1.12","content_hash":"sha256:d1225d74b75cf2bffb6ff61cb832a3086c3f23f66776b4d7138aa37776171222","tarball_url":"https://registry.emisar.dev/v1/packs/cloud-init/0.1.12/d1225d74b75cf2bffb6ff61cb832a3086c3f23f66776b4d7138aa37776171222/pack.tar.gz","actions":[{"id":"cloud-init.analyze_blame","title":"cloud-init analyze blame","summary":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","description":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Slowest modules","args":{}}],"search_terms":["slow boot","slow provisioning"],"command":{"binary":"cloud-init","argv":["analyze","blame"]}},{"id":"cloud-init.analyze_dump","title":"cloud-init analyze dump","summary":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","description":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Raw boot events JSON","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","dump"]}},{"id":"cloud-init.analyze_show","title":"cloud-init analyze show","summary":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","description":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Boot timeline","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","show"]}},{"id":"cloud-init.clean","title":"cloud-init clean","summary":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","description":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","kind":"exec","risk":"critical","side_effects":["All cloud-init state cleared.","Next boot re-runs init-local, init, config, final.","Any post-cloud-init changes that cloud-init didn't make will be left alone, BUT cloud-init modules will treat their state as fresh and may overwrite.","With `--seed`, also wipes /var/lib/cloud/seed/."],"args":[{"name":"seed","type":"boolean","required":false,"default":false,"description":"Also wipe the seed dir (NoCloud datasource)."}],"examples":[{"title":"Reset cloud-init state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.seed }}' = 'true' ]; then cloud-init clean --seed; else cloud-init clean; fi"]}},{"id":"cloud-init.clean_logs","title":"cloud-init clean --logs","summary":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","description":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","kind":"exec","risk":"medium","side_effects":["/var/log/cloud-init.log + /var/log/cloud-init-output.log truncated.","instance-id + module-run state preserved (use `clean` to also reset those)."],"args":[],"examples":[{"title":"Clear logs only","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["clean","--logs"]}},{"id":"cloud-init.cloud_config_dump","title":"cat /var/lib/cloud/instance/cloud-config.txt","summary":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes the merged cloud-config (may include secrets)."],"args":[],"examples":[{"title":"Effective cloud-config","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/cloud-config.txt"]}},{"id":"cloud-init.collect_logs","title":"cloud-init collect-logs","summary":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","description":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","kind":"exec","risk":"medium","side_effects":["Writes /tmp/cloud-init.tar.gz (overwrites if present).","May briefly stress disk + tar throughput."],"args":[],"examples":[{"title":"Collect support bundle","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["collect-logs"]}},{"id":"cloud-init.init","title":"cloud-init init","summary":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","description":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","kind":"exec","risk":"high","side_effects":["Datasource is re-fetched.","user-data / vendor-data files refreshed.","Subsequent stages (config, final) NOT re-run unless invoked."],"args":[],"examples":[{"title":"Re-run init stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init"]}},{"id":"cloud-init.init_local","title":"cloud-init init --local","summary":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","description":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","kind":"exec","risk":"high","side_effects":["Datasource detection re-runs.","Network may briefly reconfigure.","/var/lib/cloud/instance/ state files refreshed."],"args":[],"examples":[{"title":"Re-run init-local","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init","--local"]}},{"id":"cloud-init.instance_id","title":"cat /var/lib/cloud/data/instance-id","summary":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","description":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","kind":"exec","risk":"low","side_effects":["Reads one file.","No mutation."],"args":[],"examples":[{"title":"Instance id","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/data/instance-id"]}},{"id":"cloud-init.journal_tail","title":"journalctl -u cloud-init -n <lines>","summary":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","description":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","kind":"exec","risk":"low","side_effects":["Reads the systemd journal.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 journal lines","args":{}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","cloud-init","-u","cloud-init-local","-u","cloud-config","-u","cloud-final","-n","{{ args.lines }}","--no-pager"]}},{"id":"cloud-init.log_tail","title":"tail /var/log/cloud-init.log","summary":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","description":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","kind":"exec","risk":"low","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init.log"]}},{"id":"cloud-init.modules_config","title":"cloud-init modules --mode=config","summary":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","description":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","kind":"exec","risk":"high","side_effects":["Every module in the config stage re-runs.","System packages may install/update.","User accounts, ssh keys, apt sources may change.","Idempotent in design — but only as idempotent as the modules in your config."],"args":[],"examples":[{"title":"Re-apply config stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=config"]}},{"id":"cloud-init.modules_final","title":"cloud-init modules --mode=final","summary":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","description":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","kind":"exec","risk":"high","side_effects":["Every module in the final stage re-runs.","User scripts under /var/lib/cloud/scripts/per-once and per-boot may execute.","power-state-change may reboot the host."],"args":[],"examples":[{"title":"Re-apply final stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=final"]}},{"id":"cloud-init.output_log_tail","title":"tail /var/log/cloud-init-output.log","summary":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","description":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","kind":"exec","risk":"low","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines of command output","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init-output.log"]}},{"id":"cloud-init.query_metadata","title":"cloud-init query <key>","summary":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only."],"args":[{"name":"key","type":"string","required":false,"default":"--all","description":"Metadata key, or \"--all\" for everything.","validation":{"pattern":"^(--all|[a-zA-Z0-9_./\\-]{1,128})$"}}],"examples":[{"title":"All metadata","args":{}},{"title":"Instance id only","args":{"key":"instance-id"}},{"title":"Cloud-config user-data","args":{"key":"userdata"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["query","{{ args.key }}"]}},{"id":"cloud-init.schema_validate","title":"cloud-init schema --system","summary":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","description":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Validate effective config","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["schema","--system"]}},{"id":"cloud-init.single_module","title":"cloud-init single --name=<module>","summary":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","description":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","kind":"exec","risk":"high","side_effects":["One module executes.","Behavior depends on the module — could mutate users, ssh keys, hostname, packages, runcmd, etc."],"args":[{"name":"module","type":"string","required":true,"description":"Module name (e.g., users_groups, ssh, set_hostname).","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"frequency","type":"string","required":false,"default":"always","description":"When to consider the module previously run.","validation":{"enum":["always","instance","once"]}}],"examples":[{"title":"Re-run users-groups","args":{"module":"users_groups"}},{"title":"Re-run ssh module","args":{"module":"ssh"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["single","--name={{ args.module }}","--frequency={{ args.frequency }}"]}},{"id":"cloud-init.status","title":"cloud-init status","summary":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","description":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Current status","args":{}}],"search_terms":["provisioning"],"command":{"binary":"cloud-init","argv":["status"]}},{"id":"cloud-init.status_long","title":"cloud-init status --long [--wait]","summary":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","description":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","kind":"exec","risk":"low","side_effects":["One CLI call (may block up to timeout if block=true).","Read-only."],"args":[{"name":"block","type":"boolean","required":false,"default":false,"description":"Block until cloud-init exits the running state (passes --wait)."}],"examples":[{"title":"Detailed status","args":{}},{"title":"Wait for boot","args":{"block":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.block }}' = 'true' ]; then cloud-init status --long --wait; else cloud-init status --long; fi"]}},{"id":"cloud-init.userdata_dump","title":"cat /var/lib/cloud/instance/user-data.txt","summary":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw user-data (may include secrets)."],"args":[],"examples":[{"title":"Raw user-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/user-data.txt"]}},{"id":"cloud-init.vendor_data_dump","title":"cat /var/lib/cloud/instance/vendor-data.txt","summary":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw vendor-data (may include secrets)."],"args":[],"examples":[{"title":"Vendor-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/vendor-data.txt"]}},{"id":"cloud-init.version","title":"cloud-init --version","summary":"Show the build + version string for the cloud-init on this host.","description":"Show the build + version string for the cloud-init on this host.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["--version"]}}]},{"version":"0.1.11","content_hash":"sha256:b6fe92b1196b132b6abf815d2e6ddbe0e082738a1b69cd837355990b339943b6","tarball_url":"https://registry.emisar.dev/v1/packs/cloud-init/0.1.11/b6fe92b1196b132b6abf815d2e6ddbe0e082738a1b69cd837355990b339943b6/pack.tar.gz","actions":[{"id":"cloud-init.analyze_blame","title":"cloud-init analyze blame","summary":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","description":"List modules ranked by duration. The single fastest answer to \"why did cloud-init take 90 seconds?\" — the slow module is at the top.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Slowest modules","args":{}}],"search_terms":["slow boot","slow provisioning"],"command":{"binary":"cloud-init","argv":["analyze","blame"]}},{"id":"cloud-init.analyze_dump","title":"cloud-init analyze dump","summary":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","description":"Dump raw event records from cloud-init.log as JSON. Useful for downstream tooling that wants structured timing data.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Raw boot events JSON","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","dump"]}},{"id":"cloud-init.analyze_show","title":"cloud-init analyze show","summary":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","description":"Show per-stage timing for the most recent boot — when each stage started, duration, and which records contributed. Read-only.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Boot timeline","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["analyze","show"]}},{"id":"cloud-init.clean","title":"cloud-init clean","summary":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","description":"Wipe ALL cloud-init state — /var/lib/cloud/, logs, instance-id, module-run records. NEXT BOOT cloud-init treats the host as a brand-new instance and re-runs every module from scratch. Combine with a reboot to genuinely re-bootstrap the host. Catastrophic on a long-lived host where users have been added outside cloud-init — those won't be re-added.","kind":"exec","risk":"critical","side_effects":["All cloud-init state cleared.","Next boot re-runs init-local, init, config, final.","Any post-cloud-init changes that cloud-init didn't make will be left alone, BUT cloud-init modules will treat their state as fresh and may overwrite.","With `--seed`, also wipes /var/lib/cloud/seed/."],"args":[{"name":"seed","type":"boolean","required":false,"default":false,"description":"Also wipe the seed dir (NoCloud datasource)."}],"examples":[{"title":"Reset cloud-init state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.seed }}' = 'true' ]; then cloud-init clean --seed; else cloud-init clean; fi"]}},{"id":"cloud-init.clean_logs","title":"cloud-init clean --logs","summary":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","description":"Truncate cloud-init logs without resetting instance state. Use to clear noisy stale errors before re-running a stage to confirm a fix worked.","kind":"exec","risk":"medium","side_effects":["/var/log/cloud-init.log + /var/log/cloud-init-output.log truncated.","instance-id + module-run state preserved (use `clean` to also reset those)."],"args":[],"examples":[{"title":"Clear logs only","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["clean","--logs"]}},{"id":"cloud-init.cloud_config_dump","title":"cat /var/lib/cloud/instance/cloud-config.txt","summary":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump the final merged cloud-config (user-data + vendor-data + system defaults) as cloud-init evaluated it. The source of truth for \"what did cloud-init actually try to do?\". User-data classically embeds credentials, keys, and tokens, and the merged cloud-config is a superset of it; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes the merged cloud-config (may include secrets)."],"args":[],"examples":[{"title":"Effective cloud-config","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/cloud-config.txt"]}},{"id":"cloud-init.collect_logs","title":"cloud-init collect-logs","summary":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","description":"Bundle /var/log/cloud-init* + journals + config into a tarball under /tmp/cloud-init.tar.gz. Use when you need to share state with cloud-init upstream or attach to a support ticket.","kind":"exec","risk":"medium","side_effects":["Writes /tmp/cloud-init.tar.gz (overwrites if present).","May briefly stress disk + tar throughput."],"args":[],"examples":[{"title":"Collect support bundle","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["collect-logs"]}},{"id":"cloud-init.init","title":"cloud-init init","summary":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","description":"Run the (non-local) init stage — fetch user-data + vendor-data, merge cloud-config, populate /var/lib/cloud/instance/. Without `cloud-init clean` first, an unchanged instance-id is a no-op.","kind":"exec","risk":"high","side_effects":["Datasource is re-fetched.","user-data / vendor-data files refreshed.","Subsequent stages (config, final) NOT re-run unless invoked."],"args":[],"examples":[{"title":"Re-run init stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init"]}},{"id":"cloud-init.init_local","title":"cloud-init init --local","summary":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","description":"Run the init-local stage — datasource detection, fallback networking, early disk setup. Normally only runs at boot. Re-running mid-life rarely useful except for testing a datasource fix.","kind":"exec","risk":"high","side_effects":["Datasource detection re-runs.","Network may briefly reconfigure.","/var/lib/cloud/instance/ state files refreshed."],"args":[],"examples":[{"title":"Re-run init-local","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["init","--local"]}},{"id":"cloud-init.instance_id","title":"cat /var/lib/cloud/data/instance-id","summary":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","description":"Show the instance ID cloud-init currently tracks. If this differs from the cloud's idea, cloud-init thinks the machine is \"new\" and may re-run all modules at next boot.","kind":"exec","risk":"low","side_effects":["Reads one file.","No mutation."],"args":[],"examples":[{"title":"Instance id","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/data/instance-id"]}},{"id":"cloud-init.journal_tail","title":"journalctl -u cloud-init -n <lines>","summary":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","description":"Tail systemd journal entries for the four cloud-init units (cloud-init, cloud-init-local, cloud-config, cloud-final). Use when boot failed before /var/log/cloud-init.log was even written.","kind":"exec","risk":"low","side_effects":["Reads the systemd journal.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 journal lines","args":{}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","cloud-init","-u","cloud-init-local","-u","cloud-config","-u","cloud-final","-n","{{ args.lines }}","--no-pager"]}},{"id":"cloud-init.log_tail","title":"tail /var/log/cloud-init.log","summary":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","description":"Tail the main cloud-init log (last N lines). Contains module execution, errors, and per-stage timing.","kind":"exec","risk":"low","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init.log"]}},{"id":"cloud-init.modules_config","title":"cloud-init modules --mode=config","summary":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","description":"Re-run every module in the `config` stage (locale, users-groups, ssh, set-passwords, apt-pipelining, package-update-upgrade-install, etc.). Mutates the host the same way boot does. Use after fixing a buggy cloud-config — no need to reboot.","kind":"exec","risk":"high","side_effects":["Every module in the config stage re-runs.","System packages may install/update.","User accounts, ssh keys, apt sources may change.","Idempotent in design — but only as idempotent as the modules in your config."],"args":[],"examples":[{"title":"Re-apply config stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=config"]}},{"id":"cloud-init.modules_final","title":"cloud-init modules --mode=final","summary":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","description":"Re-run every module in the `final` stage (runcmd, scripts-user, phone-home, power-state-change, etc.). Anything that was scripted to run \"after first boot\" runs again. Power-state modules can reboot/shutdown — make sure your cloud-config has no power-state directive before invoking.","kind":"exec","risk":"high","side_effects":["Every module in the final stage re-runs.","User scripts under /var/lib/cloud/scripts/per-once and per-boot may execute.","power-state-change may reboot the host."],"args":[],"examples":[{"title":"Re-apply final stage","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["modules","--mode=final"]}},{"id":"cloud-init.output_log_tail","title":"tail /var/log/cloud-init-output.log","summary":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","description":"Tail captured stdout/stderr from every command cloud-init ran during boot (`runcmd`, `bootcmd`, package install, etc.). Where to look when a shell command in cloud-config silently failed.","kind":"exec","risk":"low","side_effects":["Reads one log file.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines of command output","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/cloud-init-output.log"]}},{"id":"cloud-init.query_metadata","title":"cloud-init query <key>","summary":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Pull one key out of cloud-init's runtime metadata (instance-id, hostname, region, availability_zone, …), or pass `--all` (the default) to dump everything. cloud-init redacts sensitive values only for non-root callers: as root, `--all` and the `userdata` / `vendordata` / `combined_cloud_config` keys return raw user-data, which classically embeds credentials, keys, and tokens. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only."],"args":[{"name":"key","type":"string","required":false,"default":"--all","description":"Metadata key, or \"--all\" for everything.","validation":{"pattern":"^(--all|[a-zA-Z0-9_./\\-]{1,128})$"}}],"examples":[{"title":"All metadata","args":{}},{"title":"Instance id only","args":{"key":"instance-id"}},{"title":"Cloud-config user-data","args":{"key":"userdata"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["query","{{ args.key }}"]}},{"id":"cloud-init.schema_validate","title":"cloud-init schema --system","summary":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","description":"Validate the rendered cloud-config against the cloud-init schema. Use to catch typos / deprecated keys before they cause a silent no-op on next boot.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Validate effective config","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["schema","--system"]}},{"id":"cloud-init.single_module","title":"cloud-init single --name=<module>","summary":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","description":"Run one named cloud-init module out-of-band (e.g. `users-groups`, `ssh`, `runcmd`, `set_hostname`). The module is invoked with its current configuration; effects depend entirely on which module.","kind":"exec","risk":"high","side_effects":["One module executes.","Behavior depends on the module — could mutate users, ssh keys, hostname, packages, runcmd, etc."],"args":[{"name":"module","type":"string","required":true,"description":"Module name (e.g., users_groups, ssh, set_hostname).","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"frequency","type":"string","required":false,"default":"always","description":"When to consider the module previously run.","validation":{"enum":["always","instance","once"]}}],"examples":[{"title":"Re-run users-groups","args":{"module":"users_groups"}},{"title":"Re-run ssh module","args":{"module":"ssh"}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["single","--name={{ args.module }}","--frequency={{ args.frequency }}"]}},{"id":"cloud-init.status","title":"cloud-init status","summary":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","description":"Show the current overall cloud-init state — `running`, `done`, `error`, `disabled`, or `not run`. Use as the first answer to \"did boot finish?\".","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Current status","args":{}}],"search_terms":["provisioning"],"command":{"binary":"cloud-init","argv":["status"]}},{"id":"cloud-init.status_long","title":"cloud-init status --long [--wait]","summary":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","description":"Show detailed status — per-stage state, last update, recoverable + last errors, datasource detected. With `block: true`, blocks until cloud-init finishes (useful right after boot).","kind":"exec","risk":"low","side_effects":["One CLI call (may block up to timeout if block=true).","Read-only."],"args":[{"name":"block","type":"boolean","required":false,"default":false,"description":"Block until cloud-init exits the running state (passes --wait)."}],"examples":[{"title":"Detailed status","args":{}},{"title":"Wait for boot","args":{"block":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.block }}' = 'true' ]; then cloud-init status --long --wait; else cloud-init status --long; fi"]}},{"id":"cloud-init.userdata_dump","title":"cat /var/lib/cloud/instance/user-data.txt","summary":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump raw user-data as cloud-init received it (after MIME decoding, before cloud-config merging). Compare against what you set in the launch config to confirm delivery. User-data classically embeds credentials, keys, and tokens; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw user-data (may include secrets)."],"args":[],"examples":[{"title":"Raw user-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/user-data.txt"]}},{"id":"cloud-init.vendor_data_dump","title":"cat /var/lib/cloud/instance/vendor-data.txt","summary":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Dump vendor-data the cloud provider injected (AWS / GCE / Azure provider defaults that ran before user-data). Useful when \"why is X installed that I didn't ask for?\" leads back to a vendor module. Vendor-data can embed the same credential material as user-data; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["Reads one file.","Read-only, but exposes raw vendor-data (may include secrets)."],"args":[],"examples":[{"title":"Vendor-data","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/cloud/instance/vendor-data.txt"]}},{"id":"cloud-init.version","title":"cloud-init --version","summary":"Show the build + version string for the cloud-init on this host.","description":"Show the build + version string for the cloud-init on this host.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"cloud-init","argv":["--version"]}}]}],"retired_below":"0.1.11"},{"id":"cloudflare","name":"Cloudflare edge operations","version":"0.2.6","description":"Governed Cloudflare zone, DNS record, cache-purge, security-posture, TLS, analytics, tunnel, load-balancer, Workers, Pages, and audit-log operations. Auth via CF_API_TOKEN on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/cloudflare","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/cloudflare","content_hash":"sha256:bfec1a83f3d34bdcc5cf4376ef999553b34fb334f64407b2a013dbfdf400af3c","tarball_url":"https://registry.emisar.dev/v1/packs/cloudflare/0.2.6/bfec1a83f3d34bdcc5cf4376ef999553b34fb334f64407b2a013dbfdf400af3c/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Calls the Cloudflare REST and GraphQL APIs over HTTPS. `CF_API_TOKEN` is sent in an Authorization Bearer header over curl stdin and is never placed in argv or action output. Allowlist the variable in the runner's `execution.inherit_env` configuration.","env":[{"name":"CF_API_TOKEN","required":true,"description":"Cloudflare API token. Scope it to the zones, accounts, and permissions the actions you enable need, and gate mutation actions with policy."}],"notes":["Create the token at [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens) → Create Token. Start from a read-only template and add only the permissions listed below; account-scoped tokens live under Manage Account → API Tokens.","Zone and account IDs are per-call action arguments — cf.list_zones and cf.list_accounts return them for use in the other actions.","Token scopes by family: Zone Read + DNS Read for the zone/DNS reads; DNS Edit for the DNS record mutations; Cache Purge for the purge actions; Zone Settings Edit for development mode, security level, SSL mode, minimum TLS, Always Use HTTPS, and pause; Firewall Services Edit for IP access rules; Analytics Read for zone and DNS analytics; Cloudflare Tunnel Read for tunnels; Load Balancing Read/Edit for pools; Workers Scripts Read for Worker reads and Workers Routes Edit for route changes; Pages Read for Pages reads and Pages Edit for rollback, retry, and build-cache purge; Audit Logs Read for audit logs.","Purge by hostname, prefix, or cache-tag requires a Cloudflare Enterprise zone; the other actions work on every plan.","Uploading Worker code or secrets, Workers KV/R2/D1 data planes, Cloudflare Access, WARP, Email Routing, origin CA certificates, and API token management are separate trust surfaces this pack does not touch."],"verify":"cf.list_zones"},"actions":[{"id":"cf.audit_logs","title":"List audit logs","summary":"List one bounded page of an account's Cloudflare audit log — who changed what through the dashboard and API, and when.","description":"List one bounded page of an account's Cloudflare audit log — who changed what through the dashboard and API, and when.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to read.","validation":{"min":1,"max":168}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Entries returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Last 24 hours","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.create_dns_record","title":"Create DNS record","summary":"Create one DNS record in a zone; a wrong name or content changes where live traffic and mail resolve as soon as caches expire.","description":"Create one DNS record in a zone; a wrong name or content changes where live traffic and mail resolve as soon as caches expire.","kind":"script","risk":"high","side_effects":["Resolvers pick up the new record as it propagates.","A proxied record routes its traffic through Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":true,"description":"Record type. SRV, CAA, and other data-object types are not supported by this action.","validation":{"enum":["A","AAAA","CNAME","TXT","MX","NS","PTR"]}},{"name":"name","type":"string","required":true,"description":"Record name as a FQDN (use the zone apex itself for root records). A leading \"*.\" makes it a wildcard.","validation":{"pattern":"^(\\*\\.)?([A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?\\.)*[A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?$","max_length":255}},{"name":"content","type":"string","required":true,"description":"Record content — an IP address, target hostname, or text value.","validation":{"pattern":"^[ -~]+$","max_length":2048}},{"name":"ttl","type":"integer","required":false,"default":1,"description":"TTL in seconds; 1 means automatic. Cloudflare rejects values between 2 and 59.","validation":{"min":1,"max":86400}},{"name":"proxied","type":"boolean","required":false,"default":false,"description":"Proxy A/AAAA/CNAME traffic through Cloudflare's edge. Ignored for other types."},{"name":"priority","type":"integer","required":false,"default":10,"description":"MX preference. Ignored for other types.","validation":{"min":0,"max":65535}},{"name":"comment","type":"string","required":false,"default":"","description":"Optional record comment.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Point a host at an IP","args":{"content":"203.0.113.20","name":"staging.example.com","proxied":true,"record_type":"A","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Add an SPF record","args":{"content":"v=spf1 include:_spf.example.com ~all","name":"example.com","record_type":"TXT","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.create_ip_access_rule","title":"Create IP access rule","summary":"Create a zone IP access rule that blocks, challenges, or allowlists an IP, CIDR range, ASN, or country; a wrong value can cut off legitimate visitors, and whitelist bypasses the zone's security checks for the match.","description":"Create a zone IP access rule that blocks, challenges, or allowlists an IP, CIDR range, ASN, or country; a wrong value can cut off legitimate visitors, and whitelist bypasses the zone's security checks for the match.","kind":"script","risk":"high","side_effects":["The rule applies at the edge within seconds.","whitelist exempts matching traffic from security checks."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":true,"description":"What to do with matching traffic.","validation":{"enum":["block","challenge","js_challenge","managed_challenge","whitelist"]}},{"name":"target","type":"string","required":true,"description":"What kind of value the rule matches.","validation":{"enum":["ip","ip_range","asn","country"]}},{"name":"value","type":"string","required":true,"description":"The IP address, CIDR range, AS number (AS13335), or two-letter country code to match.","validation":{"pattern":"^([0-9]{1,3}(\\.[0-9]{1,3}){3}(/([0-9]|[12][0-9]|3[012]))?|[0-9A-Fa-f:]{2,45}(/[0-9]{1,3})?|AS[0-9]{1,10}|[A-Z]{2})$","max_length":64}},{"name":"notes","type":"string","required":false,"default":"","description":"Optional note stored on the rule.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Block an attacking IP","args":{"mode":"block","notes":"SQLi attempts 2026-08-11","target":"ip","value":"198.51.100.99","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.create_worker_route","title":"Create Worker route","summary":"Create a zone Worker route that runs a script on matching URLs; a wrong pattern reroutes live traffic into Worker code. An empty script creates an exclusion route — matching requests bypass Workers and go to the origin.","description":"Create a zone Worker route that runs a script on matching URLs; a wrong pattern reroutes live traffic into Worker code. An empty script creates an exclusion route — matching requests bypass Workers and go to the origin.","kind":"script","risk":"high","side_effects":["Matching requests start executing the Worker (or bypassing Workers) within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pattern","type":"string","required":true,"description":"Route pattern, e.g. example.com/api/* — no scheme or query string.","validation":{"pattern":"^[A-Za-z0-9*.][A-Za-z0-9.*/_-]{0,511}$","max_length":512}},{"name":"script","type":"string","required":false,"default":"","description":"Worker script name to run, or empty to create a Workers-bypass route for the pattern.","validation":{"pattern":"^[A-Za-z0-9_-]{0,64}$","max_length":64}}],"examples":[{"title":"Route an API path to a Worker","args":{"pattern":"example.com/api/*","script":"api-worker","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Exclude a path from Workers","args":{"pattern":"example.com/webhooks/*","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_dns_record","title":"Delete DNS record","summary":"Delete one DNS record from a zone; whatever resolved through it stops resolving as caches expire, and the record cannot be restored except by recreating it.","description":"Delete one DNS record from a zone; whatever resolved through it stops resolving as caches expire, and the record cannot be restored except by recreating it.","kind":"script","risk":"high","side_effects":["The name stops resolving through this record as resolver caches expire."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_id","type":"string","required":true,"description":"DNS record ID (cf.dns_records returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Delete one record","args":{"record_id":"372e67954025e0ba6aaa6d586b9e0b59","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_ip_access_rule","title":"Delete IP access rule","summary":"Delete one zone IP access rule; removing a block re-admits the traffic it stopped, and removing a whitelist re-subjects that traffic to security checks.","description":"Delete one zone IP access rule; removing a block re-admits the traffic it stopped, and removing a whitelist re-subjects that traffic to security checks.","kind":"script","risk":"high","side_effects":["The rule stops applying at the edge within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"rule_id","type":"string","required":true,"description":"Access rule ID (cf.list_ip_access_rules returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Remove a rule","args":{"rule_id":"92f17202ed8bd63d69a66b86a49a8f6b","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_worker_route","title":"Delete Worker route","summary":"Delete one zone Worker route; matching requests stop executing the Worker and fall through to other routes or the origin.","description":"Delete one zone Worker route; matching requests stop executing the Worker and fall through to other routes or the origin.","kind":"script","risk":"high","side_effects":["Matching requests stop hitting the Worker within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"route_id","type":"string","required":true,"description":"Route ID (cf.list_worker_routes returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Remove a route","args":{"route_id":"e7a57d8746e74ae49c25994dadb421b1","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dev_mode_off","title":"Disable development mode","summary":"End development mode early; the edge cache resumes serving immediately and origin load drops back to normal.","description":"End development mode early; the edge cache resumes serving immediately and origin load drops back to normal.","kind":"script","risk":"medium","side_effects":["Cache resumes serving from the edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode off","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dev_mode_on","title":"Enable development mode","summary":"Enable development mode for 3 hours — the zone's cache is bypassed and the origin receives every request, which can overload a busy origin.","description":"Enable development mode for 3 hours — the zone's cache is bypassed and the origin receives every request, which can overload a busy origin.","kind":"script","risk":"high","side_effects":["Cache is bypassed for 3 hours (auto-expires).","The origin gets every request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode on","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dns_analytics_report","title":"Show DNS analytics","summary":"Show a zone's DNS query analytics for the last N hours — query counts grouped by name, record type, and response code.","description":"Show a zone's DNS query analytics for the last N hours — query counts grouped by name, record type, and response code.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to report.","validation":{"min":1,"max":72}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Result rows returned.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top query names","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dns_records","title":"List DNS records","summary":"List one bounded page of a zone's DNS records, optionally filtered by record type, name, or content.","description":"List one bounded page of a zone's DNS records, optionally filtered by record type, name, or content.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":false,"default":"","description":"Optional record type filter.","validation":{"enum":["","A","AAAA","CNAME","TXT","MX","NS","SRV","CAA","PTR"]}},{"name":"name","type":"string","required":false,"default":"","description":"Optional exact record name (FQDN) filter.","validation":{"pattern":"^[ -~]*$","max_length":255}},{"name":"content","type":"string","required":false,"default":"","description":"Optional exact record content filter.","validation":{"pattern":"^[ -~]*$","max_length":2048}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Records returned in this page.","validation":{"min":5,"max":500}}],"examples":[{"title":"All records","args":{"zone_id":"abc123def456abc123def456abc123de"}},{"title":"A records for one name","args":{"name":"www.example.com","record_type":"A","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.firewall_rules","title":"List WAF custom rules","summary":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","description":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"WAF custom rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.lb_pool_health","title":"Show pool health","summary":"Show the latest per-location health-check results for one load balancer pool's origins — where an origin is failing and why.","description":"Show the latest per-location health-check results for one load balancer pool's origins — where an origin is failing and why.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pool_id","type":"string","required":true,"description":"Pool ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pool health","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","pool_id":"17b5962d775c646f3f9725cbc7a53df4"}}],"search_terms":[]},{"id":"cf.list_accounts","title":"List accounts","summary":"List one bounded page of Cloudflare accounts the API token can read — the account IDs the tunnel, load-balancer pool, and audit-log actions need.","description":"List one bounded page of Cloudflare accounts the API token can read — the account IDs the tunnel, load-balancer pool, and audit-log actions need.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Accounts returned in this page.","validation":{"min":5,"max":50}}],"examples":[{"title":"Accounts","args":{}}],"search_terms":[]},{"id":"cf.list_certificate_packs","title":"List certificate packs","summary":"List a zone's edge certificate packs with hostnames, validity, and expiry — the certificates Cloudflare serves for the zone. Contains no private keys.","description":"List a zone's edge certificate packs with hostnames, validity, and expiry — the certificates Cloudflare serves for the zone. Contains no private keys.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Certificate packs","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_ip_access_rules","title":"List IP access rules","summary":"List one bounded page of a zone's IP access rules — the block, challenge, and allowlist entries for IPs, CIDR ranges, ASNs, and countries.","description":"List one bounded page of a zone's IP access rules — the block, challenge, and allowlist entries for IPs, CIDR ranges, ASNs, and countries.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":false,"default":"","description":"Optional rule mode filter.","validation":{"enum":["","block","challenge","js_challenge","managed_challenge","whitelist"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Rules returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"All access rules","args":{"zone_id":"abc123def456abc123def456abc123de"}},{"title":"Blocks only","args":{"mode":"block","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_lb_pools","title":"List load balancer pools","summary":"List an account's load balancer origin pools with each pool's origins, weights, enabled state, and health.","description":"List an account's load balancer origin pools with each pool's origins, weights, enabled state, and health.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pools","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_load_balancers","title":"List load balancers","summary":"List a zone's load balancers with their pool assignments, steering policy, and proxy status.","description":"List a zone's load balancers with their pool assignments, steering policy, and proxy status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Load balancers","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_pages_projects","title":"List Pages projects","summary":"List one bounded page of an account's Cloudflare Pages projects with domains, production branch, and each project's latest deployment.","description":"List one bounded page of an account's Cloudflare Pages projects with domains, production branch, and each project's latest deployment.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Projects returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Projects","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_rulesets","title":"List zone rulesets","summary":"List every ruleset attached to a zone — WAF managed and custom rules, rate limiting, redirects, transforms — with each ruleset's phase and version.","description":"List every ruleset attached to a zone — WAF managed and custom rules, rate limiting, redirects, transforms — with each ruleset's phase and version.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Rulesets","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_tunnels","title":"List Cloudflare Tunnels","summary":"List one bounded page of an account's active cloudflared tunnels with each tunnel's health status and connection summary.","description":"List one bounded page of an account's active cloudflared tunnels with each tunnel's health status and connection summary.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID (cf.list_accounts returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Tunnels returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Tunnels","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_worker_routes","title":"List Worker routes","summary":"List a zone's Worker routes — which URL patterns run which Worker script.","description":"List a zone's Worker routes — which URL patterns run which Worker script.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Worker routes","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_workers","title":"List Worker scripts","summary":"List an account's deployed Worker scripts with creation and last-modified dates. Contains names and metadata only, never script code.","description":"List an account's deployed Worker scripts with creation and last-modified dates. Contains names and metadata only, never script code.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID (cf.list_accounts returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Workers","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_zones","title":"List zones","summary":"List one bounded page of zones the API token can read, with each zone's ID, plan, status, and nameservers.","description":"List one bounded page of zones the API token can read, with each zone's ID, plan, status, and nameservers.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"name","type":"string","required":false,"default":"","description":"Optional exact zone name (domain) filter.","validation":{"pattern":"^(|[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?)*)$","max_length":253}},{"name":"status","type":"string","required":false,"default":"","description":"Optional zone status filter.","validation":{"enum":["","active","pending","initializing","moved","deactivated"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Zones returned in this page.","validation":{"min":5,"max":50}}],"examples":[{"title":"First page","args":{}},{"title":"One zone by name","args":{"name":"example.com"}}],"search_terms":[]},{"id":"cf.page_rules","title":"List page rules","summary":"List a zone's legacy page rules with their URL patterns, actions, and status.","description":"List a zone's legacy page rules with their URL patterns, actions, and status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Page rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.pages_deployment_logs","title":"Show Pages build log","summary":"Show one Pages deployment's build log for failed-build triage. The log is arbitrary build output the project's own commands printed, so it can carry anything a build script echoes — treat it as sensitive diagnostics.","description":"Show one Pages deployment's build log for failed-build triage. The log is arbitrary build output the project's own commands printed, so it can carry anything a build script echoes — treat it as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Why the build failed","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"ccccdddd-eeee-4fff-8000-111122223333","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.pages_deployments","title":"List Pages deployments","summary":"List one bounded page of a Pages project's deployments — build status, environment, trigger, and commit — newest first, optionally filtered to production or preview.","description":"List one bounded page of a Pages project's deployments — build status, environment, trigger, and commit — newest first, optionally filtered to production or preview.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name (cf.list_pages_projects returns it).","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"environment","type":"string","required":false,"default":"","description":"Optional environment filter.","validation":{"enum":["","production","preview"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Deployments returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Recent production deploys","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","environment":"production","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.pause_zone","title":"Pause zone","summary":"Pause Cloudflare on a zone — traffic goes DNS-only, straight to the origin, losing the CDN cache, WAF, and DDoS protection while exposing the origin's real IPs.","description":"Pause Cloudflare on a zone — traffic goes DNS-only, straight to the origin, losing the CDN cache, WAF, and DDoS protection while exposing the origin's real IPs.","kind":"script","risk":"high","side_effects":["The origin serves all traffic directly and its IPs become visible.","WAF rules, IP access rules, and edge caching stop applying."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pause","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_all_cache","title":"Purge entire zone cache","summary":"Purge ALL cached content for one zone; every URL misses to the origin at once, and on a busy zone that cold-cache spike can overload the origin.","description":"Purge ALL cached content for one zone; every URL misses to the origin at once, and on a busy zone that cold-cache spike can overload the origin.","kind":"script","risk":"critical","side_effects":["The origin sees a 100% miss rate until the cache re-warms.","Rate-limited by Cloudflare to roughly once per minute per zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Full purge","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_hostname","title":"Purge cached hostname","summary":"Purge every cached object for one hostname in a zone (Enterprise only); all of that host's traffic misses to the origin until the cache re-warms.","description":"Purge every cached object for one hostname in a zone (Enterprise only); all of that host's traffic misses to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request for the hostname until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hostname","type":"string","required":true,"description":"Hostname to purge.","validation":{"pattern":"^[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?)*$","max_length":253}}],"examples":[{"title":"Purge one host","args":{"hostname":"assets.example.com","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_pages_build_cache","title":"Purge Pages build cache","summary":"Purge one Pages project's build cache; live traffic is untouched, and the next build resolves dependencies from scratch and runs slower.","description":"Purge one Pages project's build cache; live traffic is untouched, and the next build resolves dependencies from scratch and runs slower.","kind":"script","risk":"medium","side_effects":["The next deployment builds cold."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}}],"examples":[{"title":"Clear a poisoned build cache","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.purge_prefix","title":"Purge cached URL prefix","summary":"Purge every cached URL under one hostname/path prefix (Enterprise only); everything under the prefix misses to the origin until the cache re-warms.","description":"Purge every cached URL under one hostname/path prefix (Enterprise only); everything under the prefix misses to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request under the prefix until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"prefix","type":"string","required":true,"description":"Prefix to purge, written as hostname/path without a scheme or query string.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*$","max_length":2048}}],"examples":[{"title":"Purge a path","args":{"prefix":"www.example.com/assets/","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_tag","title":"Purge cached tag","summary":"Purge every cached object carrying one Cache-Tag in a zone (Enterprise only); all tagged objects miss to the origin until the cache re-warms.","description":"Purge every cached object carrying one Cache-Tag in a zone (Enterprise only); all tagged objects miss to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request for tagged objects until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"tag","type":"string","required":true,"description":"Cache-Tag value to purge.","validation":{"pattern":"^[A-Za-z0-9._:/=-]{1,200}$","max_length":200}}],"examples":[{"title":"Purge a release tag","args":{"tag":"release-2026-08-11","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_url","title":"Purge cached URL","summary":"Purge one URL from a zone's edge cache; the next request for each purged variant reaches the origin and can increase origin load.","description":"Purge one URL from a zone's edge cache; the next request for each purged variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute URL to purge. Query strings are sent to Cloudflare but redacted from the audit trail.","validation":{"pattern":"^https?://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}}],"examples":[{"title":"Purge one asset","args":{"url":"https://example.com/style.css","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.retry_pages_deployment","title":"Retry Pages deployment","summary":"Re-run one Pages deployment's build; if it succeeds and is the newest production deployment, the rebuilt content goes live — retrying an old deployment can put stale content into production.","description":"Re-run one Pages deployment's build; if it succeeds and is the newest production deployment, the rebuilt content goes live — retrying an old deployment can put stale content into production.","kind":"script","risk":"high","side_effects":["A new build runs with that deployment's commit and settings.","A successful production retry becomes the live deployment."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Deployment to retry (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Retry the failed build","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"ccccdddd-eeee-4fff-8000-111122223333","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.rollback_pages_deployment","title":"Roll back Pages deployment","summary":"Roll a Pages project's production traffic back to an earlier deployment; the live site switches to that build's content immediately.","description":"Roll a Pages project's production traffic back to an earlier deployment; the live site switches to that build's content immediately.","kind":"script","risk":"high","side_effects":["Production serves the selected deployment's content within seconds.","Rolling back skips whatever the newer deployments shipped, including fixes."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Production deployment to make live again (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Back to the last good build","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"bbbbcccc-dddd-4eee-8fff-000011112222","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.set_always_use_https","title":"Set Always Use HTTPS","summary":"Turn a zone's Always Use HTTPS redirect on or off; off lets visitors stay on plain HTTP, and on breaks any resource that must be served over HTTP.","description":"Turn a zone's Always Use HTTPS redirect on or off; off lets visitors stay on plain HTTP, and on breaks any resource that must be served over HTTP.","kind":"script","risk":"high","side_effects":["on redirects every HTTP request to HTTPS at the edge.","off stops the redirect and permits plain-HTTP browsing."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"value","type":"string","required":true,"description":"Redirect state to apply.","validation":{"enum":["on","off"]}}],"examples":[{"title":"Force HTTPS","args":{"value":"on","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_lb_pool_enabled","title":"Enable or disable LB pool","summary":"Enable or disable one load balancer origin pool; disabling shifts its traffic to the remaining pools, and disabling the last healthy pool sends traffic to the fallback.","description":"Enable or disable one load balancer origin pool; disabling shifts its traffic to the remaining pools, and disabling the last healthy pool sends traffic to the fallback.","kind":"script","risk":"high","side_effects":["Load balancers steer traffic away from (or back to) the pool within seconds."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pool_id","type":"string","required":true,"description":"Pool ID (cf.list_lb_pools returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"enabled","type":"boolean","required":true,"description":"Whether the pool receives traffic."}],"examples":[{"title":"Drain a pool","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","enabled":false,"pool_id":"17b5962d775c646f3f9725cbc7a53df4"}}],"search_terms":[]},{"id":"cf.set_min_tls_version","title":"Set minimum TLS version","summary":"Set the minimum TLS version a zone accepts from visitors; raising it cuts off legacy clients, and lowering it re-admits protocol versions with known weaknesses.","description":"Set the minimum TLS version a zone accepts from visitors; raising it cuts off legacy clients, and lowering it re-admits protocol versions with known weaknesses.","kind":"script","risk":"high","side_effects":["Clients below the minimum fail their TLS handshake."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"version","type":"string","required":true,"description":"Minimum TLS version to accept.","validation":{"enum":["1.0","1.1","1.2","1.3"]}}],"examples":[{"title":"Require TLS 1.2","args":{"version":"1.2","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_security_level","title":"Set security level","summary":"Set a zone's security level, including I'm Under Attack mode; under_attack challenges every visitor, and lowering the level exposes the origin to more hostile traffic.","description":"Set a zone's security level, including I'm Under Attack mode; under_attack challenges every visitor, and lowering the level exposes the origin to more hostile traffic.","kind":"script","risk":"high","side_effects":["under_attack serves an interstitial challenge to every visitor, including API clients.","Lowering the level admits traffic the previous level challenged or blocked."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"level","type":"string","required":true,"description":"Security level to apply.","validation":{"enum":["essentially_off","low","medium","high","under_attack"]}}],"examples":[{"title":"Under attack","args":{"level":"under_attack","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Back to medium","args":{"level":"medium","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_ssl_mode","title":"Set SSL mode","summary":"Set a zone's edge-to-origin SSL mode; a downgrade (full to flexible or off) sends visitor traffic to the origin unencrypted, and strict breaks the site if the origin certificate is invalid.","description":"Set a zone's edge-to-origin SSL mode; a downgrade (full to flexible or off) sends visitor traffic to the origin unencrypted, and strict breaks the site if the origin certificate is invalid.","kind":"script","risk":"high","side_effects":["flexible and off carry origin traffic over plain HTTP.","strict fails requests when the origin certificate is untrusted or expired."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":true,"description":"SSL mode to apply.","validation":{"enum":["off","flexible","full","strict"]}}],"examples":[{"title":"Full (strict)","args":{"mode":"strict","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.ssl_verification","title":"Show SSL verification status","summary":"Show edge certificate verification status for a zone's hostnames — what a browser will be served and whether validation is stuck.","description":"Show edge certificate verification status for a zone's hostnames — what a browser will be served and whether validation is stuck.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Verification status","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.tunnel_connections","title":"Show tunnel connections","summary":"Show one tunnel's active cloudflared connectors — client version, architecture, origin IP, and the edge locations each connection is landed on.","description":"Show one tunnel's active cloudflared connectors — client version, architecture, origin IP, and the edge locations each connection is landed on.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"tunnel_id","type":"string","required":true,"description":"Tunnel ID (UUID).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Connector status","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","tunnel_id":"f70a3b21-9c86-4dcb-8d5e-1f2a3b4c5d6e"}}],"search_terms":[]},{"id":"cf.unpause_zone","title":"Unpause zone","summary":"Resume Cloudflare on a paused zone; proxied traffic returns to the edge and the CDN cache, WAF, and DDoS protection re-engage.","description":"Resume Cloudflare on a paused zone; proxied traffic returns to the edge and the CDN cache, WAF, and DDoS protection re-engage.","kind":"script","risk":"medium","side_effects":["Proxied traffic moves back through Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Unpause","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.update_dns_record","title":"Update DNS record","summary":"Change fields on one existing DNS record; a wrong content or proxy flip reroutes live traffic as soon as caches expire. Empty or zero arguments leave that field unchanged, and at least one field must change.","description":"Change fields on one existing DNS record; a wrong content or proxy flip reroutes live traffic as soon as caches expire. Empty or zero arguments leave that field unchanged, and at least one field must change.","kind":"script","risk":"high","side_effects":["Resolvers pick up the changed record as it propagates.","Flipping proxied moves traffic onto or off Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_id","type":"string","required":true,"description":"DNS record ID (cf.dns_records returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":false,"default":"","description":"New record type, or empty to leave unchanged.","validation":{"enum":["","A","AAAA","CNAME","TXT","MX","NS","PTR"]}},{"name":"name","type":"string","required":false,"default":"","description":"New record name (FQDN), or empty to leave unchanged.","validation":{"pattern":"^(|(\\*\\.)?([A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?\\.)*[A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?)$","max_length":255}},{"name":"content","type":"string","required":false,"default":"","description":"New record content, or empty to leave unchanged.","validation":{"pattern":"^[ -~]*$","max_length":2048}},{"name":"ttl","type":"integer","required":false,"default":0,"description":"New TTL in seconds (1 means automatic), or 0 to leave unchanged.","validation":{"min":0,"max":86400}},{"name":"proxied","type":"string","required":false,"default":"","description":"New proxy state for A/AAAA/CNAME records, or empty to leave unchanged.","validation":{"enum":["","true","false"]}},{"name":"comment","type":"string","required":false,"default":"","description":"New record comment, or empty to leave unchanged.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Repoint a record","args":{"content":"203.0.113.30","record_id":"372e67954025e0ba6aaa6d586b9e0b59","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.update_worker_route","title":"Update Worker route","summary":"Replace one Worker route's pattern and script; a wrong pattern or script reroutes live traffic, and an empty script turns the route into a Workers bypass for matching requests.","description":"Replace one Worker route's pattern and script; a wrong pattern or script reroutes live traffic, and an empty script turns the route into a Workers bypass for matching requests.","kind":"script","risk":"high","side_effects":["Matching requests switch to the new script (or bypass Workers) within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"route_id","type":"string","required":true,"description":"Route ID (cf.list_worker_routes returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pattern","type":"string","required":true,"description":"Route pattern to apply — the update replaces the whole route, so pass the full intended pattern.","validation":{"pattern":"^[A-Za-z0-9*.][A-Za-z0-9.*/_-]{0,511}$","max_length":512}},{"name":"script","type":"string","required":false,"default":"","description":"Worker script name to run, or empty to detach Workers from the pattern.","validation":{"pattern":"^[A-Za-z0-9_-]{0,64}$","max_length":64}}],"examples":[{"title":"Point a route at a hotfix Worker","args":{"pattern":"example.com/api/*","route_id":"e7a57d8746e74ae49c25994dadb421b1","script":"api-worker-hotfix","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.worker_deployments","title":"Show Worker deployments","summary":"Show one Worker script's deployment history — who deployed which version when, and the live gradual-rollout percentage split.","description":"Show one Worker script's deployment history — who deployed which version when, and the live gradual-rollout percentage split.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"script_name","type":"string","required":true,"description":"Worker script name (cf.list_workers returns it).","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_-]{0,63}$","max_length":64}}],"examples":[{"title":"Deployment history","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","script_name":"api-worker"}}],"search_terms":[]},{"id":"cf.zone_analytics","title":"Show zone HTTP analytics","summary":"Show a zone's HTTP traffic for the last N hours via the GraphQL analytics API — request, bandwidth, cached, threat, and unique-visitor totals plus the hourly series. Replaces the legacy /analytics/dashboard API, which Cloudflare sunset.","description":"Show a zone's HTTP traffic for the last N hours via the GraphQL analytics API — request, bandwidth, cached, threat, and unique-visitor totals plus the hourly series. Replaces the legacy /analytics/dashboard API, which Cloudflare sunset.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to report.","validation":{"min":1,"max":72}}],"examples":[{"title":"Last 24 hours","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.zone_details","title":"Show zone details","summary":"Show one zone's status, plan, nameservers, and activation state.","description":"Show one zone's status, plan, nameservers, and activation state.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Zone details","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.zone_settings","title":"List zone settings","summary":"List every zone-level setting — cache level, security level, SSL mode, minimum TLS version, development mode, Always Use HTTPS, and the rest.","description":"List every zone-level setting — cache level, security level, SSL mode, minimum TLS version, development mode, Always Use HTTPS, and the rest.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Settings","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]}],"previous_versions":[{"version":"0.2.5","content_hash":"sha256:0fb2509b6fce9581dd11c20ae98bef592c2dbb07fc7ec2f3c22067882c6264ae","tarball_url":"https://registry.emisar.dev/v1/packs/cloudflare/0.2.5/0fb2509b6fce9581dd11c20ae98bef592c2dbb07fc7ec2f3c22067882c6264ae/pack.tar.gz","actions":[{"id":"cf.audit_logs","title":"List audit logs","summary":"List one bounded page of an account's Cloudflare audit log — who changed what through the dashboard and API, and when.","description":"List one bounded page of an account's Cloudflare audit log — who changed what through the dashboard and API, and when.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to read.","validation":{"min":1,"max":168}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Entries returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Last 24 hours","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.create_dns_record","title":"Create DNS record","summary":"Create one DNS record in a zone; a wrong name or content changes where live traffic and mail resolve as soon as caches expire.","description":"Create one DNS record in a zone; a wrong name or content changes where live traffic and mail resolve as soon as caches expire.","kind":"script","risk":"high","side_effects":["Resolvers pick up the new record as it propagates.","A proxied record routes its traffic through Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":true,"description":"Record type. SRV, CAA, and other data-object types are not supported by this action.","validation":{"enum":["A","AAAA","CNAME","TXT","MX","NS","PTR"]}},{"name":"name","type":"string","required":true,"description":"Record name as a FQDN (use the zone apex itself for root records). A leading \"*.\" makes it a wildcard.","validation":{"pattern":"^(\\*\\.)?([A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?\\.)*[A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?$","max_length":255}},{"name":"content","type":"string","required":true,"description":"Record content — an IP address, target hostname, or text value.","validation":{"pattern":"^[ -~]+$","max_length":2048}},{"name":"ttl","type":"integer","required":false,"default":1,"description":"TTL in seconds; 1 means automatic. Cloudflare rejects values between 2 and 59.","validation":{"min":1,"max":86400}},{"name":"proxied","type":"boolean","required":false,"default":false,"description":"Proxy A/AAAA/CNAME traffic through Cloudflare's edge. Ignored for other types."},{"name":"priority","type":"integer","required":false,"default":10,"description":"MX preference. Ignored for other types.","validation":{"min":0,"max":65535}},{"name":"comment","type":"string","required":false,"default":"","description":"Optional record comment.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Point a host at an IP","args":{"content":"203.0.113.20","name":"staging.example.com","proxied":true,"record_type":"A","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Add an SPF record","args":{"content":"v=spf1 include:_spf.example.com ~all","name":"example.com","record_type":"TXT","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.create_ip_access_rule","title":"Create IP access rule","summary":"Create a zone IP access rule that blocks, challenges, or allowlists an IP, CIDR range, ASN, or country; a wrong value can cut off legitimate visitors, and whitelist bypasses the zone's security checks for the match.","description":"Create a zone IP access rule that blocks, challenges, or allowlists an IP, CIDR range, ASN, or country; a wrong value can cut off legitimate visitors, and whitelist bypasses the zone's security checks for the match.","kind":"script","risk":"high","side_effects":["The rule applies at the edge within seconds.","whitelist exempts matching traffic from security checks."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":true,"description":"What to do with matching traffic.","validation":{"enum":["block","challenge","js_challenge","managed_challenge","whitelist"]}},{"name":"target","type":"string","required":true,"description":"What kind of value the rule matches.","validation":{"enum":["ip","ip_range","asn","country"]}},{"name":"value","type":"string","required":true,"description":"The IP address, CIDR range, AS number (AS13335), or two-letter country code to match.","validation":{"pattern":"^([0-9]{1,3}(\\.[0-9]{1,3}){3}(/([0-9]|[12][0-9]|3[012]))?|[0-9A-Fa-f:]{2,45}(/[0-9]{1,3})?|AS[0-9]{1,10}|[A-Z]{2})$","max_length":64}},{"name":"notes","type":"string","required":false,"default":"","description":"Optional note stored on the rule.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Block an attacking IP","args":{"mode":"block","notes":"SQLi attempts 2026-08-11","target":"ip","value":"198.51.100.99","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.create_worker_route","title":"Create Worker route","summary":"Create a zone Worker route that runs a script on matching URLs; a wrong pattern reroutes live traffic into Worker code. An empty script creates an exclusion route — matching requests bypass Workers and go to the origin.","description":"Create a zone Worker route that runs a script on matching URLs; a wrong pattern reroutes live traffic into Worker code. An empty script creates an exclusion route — matching requests bypass Workers and go to the origin.","kind":"script","risk":"high","side_effects":["Matching requests start executing the Worker (or bypassing Workers) within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pattern","type":"string","required":true,"description":"Route pattern, e.g. example.com/api/* — no scheme or query string.","validation":{"pattern":"^[A-Za-z0-9*.][A-Za-z0-9.*/_-]{0,511}$","max_length":512}},{"name":"script","type":"string","required":false,"default":"","description":"Worker script name to run, or empty to create a Workers-bypass route for the pattern.","validation":{"pattern":"^[A-Za-z0-9_-]{0,64}$","max_length":64}}],"examples":[{"title":"Route an API path to a Worker","args":{"pattern":"example.com/api/*","script":"api-worker","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Exclude a path from Workers","args":{"pattern":"example.com/webhooks/*","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_dns_record","title":"Delete DNS record","summary":"Delete one DNS record from a zone; whatever resolved through it stops resolving as caches expire, and the record cannot be restored except by recreating it.","description":"Delete one DNS record from a zone; whatever resolved through it stops resolving as caches expire, and the record cannot be restored except by recreating it.","kind":"script","risk":"high","side_effects":["The name stops resolving through this record as resolver caches expire."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_id","type":"string","required":true,"description":"DNS record ID (cf.dns_records returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Delete one record","args":{"record_id":"372e67954025e0ba6aaa6d586b9e0b59","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_ip_access_rule","title":"Delete IP access rule","summary":"Delete one zone IP access rule; removing a block re-admits the traffic it stopped, and removing a whitelist re-subjects that traffic to security checks.","description":"Delete one zone IP access rule; removing a block re-admits the traffic it stopped, and removing a whitelist re-subjects that traffic to security checks.","kind":"script","risk":"high","side_effects":["The rule stops applying at the edge within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"rule_id","type":"string","required":true,"description":"Access rule ID (cf.list_ip_access_rules returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Remove a rule","args":{"rule_id":"92f17202ed8bd63d69a66b86a49a8f6b","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_worker_route","title":"Delete Worker route","summary":"Delete one zone Worker route; matching requests stop executing the Worker and fall through to other routes or the origin.","description":"Delete one zone Worker route; matching requests stop executing the Worker and fall through to other routes or the origin.","kind":"script","risk":"high","side_effects":["Matching requests stop hitting the Worker within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"route_id","type":"string","required":true,"description":"Route ID (cf.list_worker_routes returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Remove a route","args":{"route_id":"e7a57d8746e74ae49c25994dadb421b1","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dev_mode_off","title":"Disable development mode","summary":"End development mode early; the edge cache resumes serving immediately and origin load drops back to normal.","description":"End development mode early; the edge cache resumes serving immediately and origin load drops back to normal.","kind":"script","risk":"medium","side_effects":["Cache resumes serving from the edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode off","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dev_mode_on","title":"Enable development mode","summary":"Enable development mode for 3 hours — the zone's cache is bypassed and the origin receives every request, which can overload a busy origin.","description":"Enable development mode for 3 hours — the zone's cache is bypassed and the origin receives every request, which can overload a busy origin.","kind":"script","risk":"high","side_effects":["Cache is bypassed for 3 hours (auto-expires).","The origin gets every request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode on","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dns_analytics_report","title":"Show DNS analytics","summary":"Show a zone's DNS query analytics for the last N hours — query counts grouped by name, record type, and response code.","description":"Show a zone's DNS query analytics for the last N hours — query counts grouped by name, record type, and response code.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to report.","validation":{"min":1,"max":72}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Result rows returned.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top query names","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dns_records","title":"List DNS records","summary":"List one bounded page of a zone's DNS records, optionally filtered by record type, name, or content.","description":"List one bounded page of a zone's DNS records, optionally filtered by record type, name, or content.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":false,"default":"","description":"Optional record type filter.","validation":{"enum":["","A","AAAA","CNAME","TXT","MX","NS","SRV","CAA","PTR"]}},{"name":"name","type":"string","required":false,"default":"","description":"Optional exact record name (FQDN) filter.","validation":{"pattern":"^[ -~]*$","max_length":255}},{"name":"content","type":"string","required":false,"default":"","description":"Optional exact record content filter.","validation":{"pattern":"^[ -~]*$","max_length":2048}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Records returned in this page.","validation":{"min":5,"max":500}}],"examples":[{"title":"All records","args":{"zone_id":"abc123def456abc123def456abc123de"}},{"title":"A records for one name","args":{"name":"www.example.com","record_type":"A","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.firewall_rules","title":"List WAF custom rules","summary":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","description":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"WAF custom rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.lb_pool_health","title":"Show pool health","summary":"Show the latest per-location health-check results for one load balancer pool's origins — where an origin is failing and why.","description":"Show the latest per-location health-check results for one load balancer pool's origins — where an origin is failing and why.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pool_id","type":"string","required":true,"description":"Pool ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pool health","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","pool_id":"17b5962d775c646f3f9725cbc7a53df4"}}],"search_terms":[]},{"id":"cf.list_accounts","title":"List accounts","summary":"List one bounded page of Cloudflare accounts the API token can read — the account IDs the tunnel, load-balancer pool, and audit-log actions need.","description":"List one bounded page of Cloudflare accounts the API token can read — the account IDs the tunnel, load-balancer pool, and audit-log actions need.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Accounts returned in this page.","validation":{"min":5,"max":50}}],"examples":[{"title":"Accounts","args":{}}],"search_terms":[]},{"id":"cf.list_certificate_packs","title":"List certificate packs","summary":"List a zone's edge certificate packs with hostnames, validity, and expiry — the certificates Cloudflare serves for the zone. Contains no private keys.","description":"List a zone's edge certificate packs with hostnames, validity, and expiry — the certificates Cloudflare serves for the zone. Contains no private keys.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Certificate packs","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_ip_access_rules","title":"List IP access rules","summary":"List one bounded page of a zone's IP access rules — the block, challenge, and allowlist entries for IPs, CIDR ranges, ASNs, and countries.","description":"List one bounded page of a zone's IP access rules — the block, challenge, and allowlist entries for IPs, CIDR ranges, ASNs, and countries.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":false,"default":"","description":"Optional rule mode filter.","validation":{"enum":["","block","challenge","js_challenge","managed_challenge","whitelist"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Rules returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"All access rules","args":{"zone_id":"abc123def456abc123def456abc123de"}},{"title":"Blocks only","args":{"mode":"block","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_lb_pools","title":"List load balancer pools","summary":"List an account's load balancer origin pools with each pool's origins, weights, enabled state, and health.","description":"List an account's load balancer origin pools with each pool's origins, weights, enabled state, and health.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pools","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_load_balancers","title":"List load balancers","summary":"List a zone's load balancers with their pool assignments, steering policy, and proxy status.","description":"List a zone's load balancers with their pool assignments, steering policy, and proxy status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Load balancers","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_pages_projects","title":"List Pages projects","summary":"List one bounded page of an account's Cloudflare Pages projects with domains, production branch, and each project's latest deployment.","description":"List one bounded page of an account's Cloudflare Pages projects with domains, production branch, and each project's latest deployment.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Projects returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Projects","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_rulesets","title":"List zone rulesets","summary":"List every ruleset attached to a zone — WAF managed and custom rules, rate limiting, redirects, transforms — with each ruleset's phase and version.","description":"List every ruleset attached to a zone — WAF managed and custom rules, rate limiting, redirects, transforms — with each ruleset's phase and version.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Rulesets","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_tunnels","title":"List Cloudflare Tunnels","summary":"List one bounded page of an account's active cloudflared tunnels with each tunnel's health status and connection summary.","description":"List one bounded page of an account's active cloudflared tunnels with each tunnel's health status and connection summary.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID (cf.list_accounts returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Tunnels returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Tunnels","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_worker_routes","title":"List Worker routes","summary":"List a zone's Worker routes — which URL patterns run which Worker script.","description":"List a zone's Worker routes — which URL patterns run which Worker script.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Worker routes","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_workers","title":"List Worker scripts","summary":"List an account's deployed Worker scripts with creation and last-modified dates. Contains names and metadata only, never script code.","description":"List an account's deployed Worker scripts with creation and last-modified dates. Contains names and metadata only, never script code.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID (cf.list_accounts returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Workers","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_zones","title":"List zones","summary":"List one bounded page of zones the API token can read, with each zone's ID, plan, status, and nameservers.","description":"List one bounded page of zones the API token can read, with each zone's ID, plan, status, and nameservers.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"name","type":"string","required":false,"default":"","description":"Optional exact zone name (domain) filter.","validation":{"pattern":"^(|[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?)*)$","max_length":253}},{"name":"status","type":"string","required":false,"default":"","description":"Optional zone status filter.","validation":{"enum":["","active","pending","initializing","moved","deactivated"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Zones returned in this page.","validation":{"min":5,"max":50}}],"examples":[{"title":"First page","args":{}},{"title":"One zone by name","args":{"name":"example.com"}}],"search_terms":[]},{"id":"cf.page_rules","title":"List page rules","summary":"List a zone's legacy page rules with their URL patterns, actions, and status.","description":"List a zone's legacy page rules with their URL patterns, actions, and status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Page rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.pages_deployment_logs","title":"Show Pages build log","summary":"Show one Pages deployment's build log for failed-build triage. The log is arbitrary build output the project's own commands printed, so it can carry anything a build script echoes — treat it as sensitive diagnostics.","description":"Show one Pages deployment's build log for failed-build triage. The log is arbitrary build output the project's own commands printed, so it can carry anything a build script echoes — treat it as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Why the build failed","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"ccccdddd-eeee-4fff-8000-111122223333","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.pages_deployments","title":"List Pages deployments","summary":"List one bounded page of a Pages project's deployments — build status, environment, trigger, and commit — newest first, optionally filtered to production or preview.","description":"List one bounded page of a Pages project's deployments — build status, environment, trigger, and commit — newest first, optionally filtered to production or preview.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name (cf.list_pages_projects returns it).","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"environment","type":"string","required":false,"default":"","description":"Optional environment filter.","validation":{"enum":["","production","preview"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Deployments returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Recent production deploys","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","environment":"production","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.pause_zone","title":"Pause zone","summary":"Pause Cloudflare on a zone — traffic goes DNS-only, straight to the origin, losing the CDN cache, WAF, and DDoS protection while exposing the origin's real IPs.","description":"Pause Cloudflare on a zone — traffic goes DNS-only, straight to the origin, losing the CDN cache, WAF, and DDoS protection while exposing the origin's real IPs.","kind":"script","risk":"high","side_effects":["The origin serves all traffic directly and its IPs become visible.","WAF rules, IP access rules, and edge caching stop applying."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pause","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_all_cache","title":"Purge entire zone cache","summary":"Purge ALL cached content for one zone; every URL misses to the origin at once, and on a busy zone that cold-cache spike can overload the origin.","description":"Purge ALL cached content for one zone; every URL misses to the origin at once, and on a busy zone that cold-cache spike can overload the origin.","kind":"script","risk":"critical","side_effects":["The origin sees a 100% miss rate until the cache re-warms.","Rate-limited by Cloudflare to roughly once per minute per zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Full purge","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_hostname","title":"Purge cached hostname","summary":"Purge every cached object for one hostname in a zone (Enterprise only); all of that host's traffic misses to the origin until the cache re-warms.","description":"Purge every cached object for one hostname in a zone (Enterprise only); all of that host's traffic misses to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request for the hostname until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hostname","type":"string","required":true,"description":"Hostname to purge.","validation":{"pattern":"^[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?)*$","max_length":253}}],"examples":[{"title":"Purge one host","args":{"hostname":"assets.example.com","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_pages_build_cache","title":"Purge Pages build cache","summary":"Purge one Pages project's build cache; live traffic is untouched, and the next build resolves dependencies from scratch and runs slower.","description":"Purge one Pages project's build cache; live traffic is untouched, and the next build resolves dependencies from scratch and runs slower.","kind":"script","risk":"medium","side_effects":["The next deployment builds cold."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}}],"examples":[{"title":"Clear a poisoned build cache","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.purge_prefix","title":"Purge cached URL prefix","summary":"Purge every cached URL under one hostname/path prefix (Enterprise only); everything under the prefix misses to the origin until the cache re-warms.","description":"Purge every cached URL under one hostname/path prefix (Enterprise only); everything under the prefix misses to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request under the prefix until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"prefix","type":"string","required":true,"description":"Prefix to purge, written as hostname/path without a scheme or query string.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*$","max_length":2048}}],"examples":[{"title":"Purge a path","args":{"prefix":"www.example.com/assets/","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_tag","title":"Purge cached tag","summary":"Purge every cached object carrying one Cache-Tag in a zone (Enterprise only); all tagged objects miss to the origin until the cache re-warms.","description":"Purge every cached object carrying one Cache-Tag in a zone (Enterprise only); all tagged objects miss to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request for tagged objects until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"tag","type":"string","required":true,"description":"Cache-Tag value to purge.","validation":{"pattern":"^[A-Za-z0-9._:/=-]{1,200}$","max_length":200}}],"examples":[{"title":"Purge a release tag","args":{"tag":"release-2026-08-11","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_url","title":"Purge cached URL","summary":"Purge one URL from a zone's edge cache; the next request for each purged variant reaches the origin and can increase origin load.","description":"Purge one URL from a zone's edge cache; the next request for each purged variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute URL to purge. Query strings are sent to Cloudflare but redacted from the audit trail.","validation":{"pattern":"^https?://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}}],"examples":[{"title":"Purge one asset","args":{"url":"https://example.com/style.css","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.retry_pages_deployment","title":"Retry Pages deployment","summary":"Re-run one Pages deployment's build; if it succeeds and is the newest production deployment, the rebuilt content goes live — retrying an old deployment can put stale content into production.","description":"Re-run one Pages deployment's build; if it succeeds and is the newest production deployment, the rebuilt content goes live — retrying an old deployment can put stale content into production.","kind":"script","risk":"high","side_effects":["A new build runs with that deployment's commit and settings.","A successful production retry becomes the live deployment."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Deployment to retry (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Retry the failed build","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"ccccdddd-eeee-4fff-8000-111122223333","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.rollback_pages_deployment","title":"Roll back Pages deployment","summary":"Roll a Pages project's production traffic back to an earlier deployment; the live site switches to that build's content immediately.","description":"Roll a Pages project's production traffic back to an earlier deployment; the live site switches to that build's content immediately.","kind":"script","risk":"high","side_effects":["Production serves the selected deployment's content within seconds.","Rolling back skips whatever the newer deployments shipped, including fixes."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Production deployment to make live again (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Back to the last good build","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"bbbbcccc-dddd-4eee-8fff-000011112222","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.set_always_use_https","title":"Set Always Use HTTPS","summary":"Turn a zone's Always Use HTTPS redirect on or off; off lets visitors stay on plain HTTP, and on breaks any resource that must be served over HTTP.","description":"Turn a zone's Always Use HTTPS redirect on or off; off lets visitors stay on plain HTTP, and on breaks any resource that must be served over HTTP.","kind":"script","risk":"high","side_effects":["on redirects every HTTP request to HTTPS at the edge.","off stops the redirect and permits plain-HTTP browsing."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"value","type":"string","required":true,"description":"Redirect state to apply.","validation":{"enum":["on","off"]}}],"examples":[{"title":"Force HTTPS","args":{"value":"on","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_lb_pool_enabled","title":"Enable or disable LB pool","summary":"Enable or disable one load balancer origin pool; disabling shifts its traffic to the remaining pools, and disabling the last healthy pool sends traffic to the fallback.","description":"Enable or disable one load balancer origin pool; disabling shifts its traffic to the remaining pools, and disabling the last healthy pool sends traffic to the fallback.","kind":"script","risk":"high","side_effects":["Load balancers steer traffic away from (or back to) the pool within seconds."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pool_id","type":"string","required":true,"description":"Pool ID (cf.list_lb_pools returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"enabled","type":"boolean","required":true,"description":"Whether the pool receives traffic."}],"examples":[{"title":"Drain a pool","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","enabled":false,"pool_id":"17b5962d775c646f3f9725cbc7a53df4"}}],"search_terms":[]},{"id":"cf.set_min_tls_version","title":"Set minimum TLS version","summary":"Set the minimum TLS version a zone accepts from visitors; raising it cuts off legacy clients, and lowering it re-admits protocol versions with known weaknesses.","description":"Set the minimum TLS version a zone accepts from visitors; raising it cuts off legacy clients, and lowering it re-admits protocol versions with known weaknesses.","kind":"script","risk":"high","side_effects":["Clients below the minimum fail their TLS handshake."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"version","type":"string","required":true,"description":"Minimum TLS version to accept.","validation":{"enum":["1.0","1.1","1.2","1.3"]}}],"examples":[{"title":"Require TLS 1.2","args":{"version":"1.2","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_security_level","title":"Set security level","summary":"Set a zone's security level, including I'm Under Attack mode; under_attack challenges every visitor, and lowering the level exposes the origin to more hostile traffic.","description":"Set a zone's security level, including I'm Under Attack mode; under_attack challenges every visitor, and lowering the level exposes the origin to more hostile traffic.","kind":"script","risk":"high","side_effects":["under_attack serves an interstitial challenge to every visitor, including API clients.","Lowering the level admits traffic the previous level challenged or blocked."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"level","type":"string","required":true,"description":"Security level to apply.","validation":{"enum":["essentially_off","low","medium","high","under_attack"]}}],"examples":[{"title":"Under attack","args":{"level":"under_attack","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Back to medium","args":{"level":"medium","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_ssl_mode","title":"Set SSL mode","summary":"Set a zone's edge-to-origin SSL mode; a downgrade (full to flexible or off) sends visitor traffic to the origin unencrypted, and strict breaks the site if the origin certificate is invalid.","description":"Set a zone's edge-to-origin SSL mode; a downgrade (full to flexible or off) sends visitor traffic to the origin unencrypted, and strict breaks the site if the origin certificate is invalid.","kind":"script","risk":"high","side_effects":["flexible and off carry origin traffic over plain HTTP.","strict fails requests when the origin certificate is untrusted or expired."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":true,"description":"SSL mode to apply.","validation":{"enum":["off","flexible","full","strict"]}}],"examples":[{"title":"Full (strict)","args":{"mode":"strict","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.ssl_verification","title":"Show SSL verification status","summary":"Show edge certificate verification status for a zone's hostnames — what a browser will be served and whether validation is stuck.","description":"Show edge certificate verification status for a zone's hostnames — what a browser will be served and whether validation is stuck.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Verification status","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.tunnel_connections","title":"Show tunnel connections","summary":"Show one tunnel's active cloudflared connectors — client version, architecture, origin IP, and the edge locations each connection is landed on.","description":"Show one tunnel's active cloudflared connectors — client version, architecture, origin IP, and the edge locations each connection is landed on.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"tunnel_id","type":"string","required":true,"description":"Tunnel ID (UUID).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Connector status","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","tunnel_id":"f70a3b21-9c86-4dcb-8d5e-1f2a3b4c5d6e"}}],"search_terms":[]},{"id":"cf.unpause_zone","title":"Unpause zone","summary":"Resume Cloudflare on a paused zone; proxied traffic returns to the edge and the CDN cache, WAF, and DDoS protection re-engage.","description":"Resume Cloudflare on a paused zone; proxied traffic returns to the edge and the CDN cache, WAF, and DDoS protection re-engage.","kind":"script","risk":"medium","side_effects":["Proxied traffic moves back through Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Unpause","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.update_dns_record","title":"Update DNS record","summary":"Change fields on one existing DNS record; a wrong content or proxy flip reroutes live traffic as soon as caches expire. Empty or zero arguments leave that field unchanged, and at least one field must change.","description":"Change fields on one existing DNS record; a wrong content or proxy flip reroutes live traffic as soon as caches expire. Empty or zero arguments leave that field unchanged, and at least one field must change.","kind":"script","risk":"high","side_effects":["Resolvers pick up the changed record as it propagates.","Flipping proxied moves traffic onto or off Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_id","type":"string","required":true,"description":"DNS record ID (cf.dns_records returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":false,"default":"","description":"New record type, or empty to leave unchanged.","validation":{"enum":["","A","AAAA","CNAME","TXT","MX","NS","PTR"]}},{"name":"name","type":"string","required":false,"default":"","description":"New record name (FQDN), or empty to leave unchanged.","validation":{"pattern":"^(|(\\*\\.)?([A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?\\.)*[A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?)$","max_length":255}},{"name":"content","type":"string","required":false,"default":"","description":"New record content, or empty to leave unchanged.","validation":{"pattern":"^[ -~]*$","max_length":2048}},{"name":"ttl","type":"integer","required":false,"default":0,"description":"New TTL in seconds (1 means automatic), or 0 to leave unchanged.","validation":{"min":0,"max":86400}},{"name":"proxied","type":"string","required":false,"default":"","description":"New proxy state for A/AAAA/CNAME records, or empty to leave unchanged.","validation":{"enum":["","true","false"]}},{"name":"comment","type":"string","required":false,"default":"","description":"New record comment, or empty to leave unchanged.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Repoint a record","args":{"content":"203.0.113.30","record_id":"372e67954025e0ba6aaa6d586b9e0b59","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.update_worker_route","title":"Update Worker route","summary":"Replace one Worker route's pattern and script; a wrong pattern or script reroutes live traffic, and an empty script turns the route into a Workers bypass for matching requests.","description":"Replace one Worker route's pattern and script; a wrong pattern or script reroutes live traffic, and an empty script turns the route into a Workers bypass for matching requests.","kind":"script","risk":"high","side_effects":["Matching requests switch to the new script (or bypass Workers) within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"route_id","type":"string","required":true,"description":"Route ID (cf.list_worker_routes returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pattern","type":"string","required":true,"description":"Route pattern to apply — the update replaces the whole route, so pass the full intended pattern.","validation":{"pattern":"^[A-Za-z0-9*.][A-Za-z0-9.*/_-]{0,511}$","max_length":512}},{"name":"script","type":"string","required":false,"default":"","description":"Worker script name to run, or empty to detach Workers from the pattern.","validation":{"pattern":"^[A-Za-z0-9_-]{0,64}$","max_length":64}}],"examples":[{"title":"Point a route at a hotfix Worker","args":{"pattern":"example.com/api/*","route_id":"e7a57d8746e74ae49c25994dadb421b1","script":"api-worker-hotfix","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.worker_deployments","title":"Show Worker deployments","summary":"Show one Worker script's deployment history — who deployed which version when, and the live gradual-rollout percentage split.","description":"Show one Worker script's deployment history — who deployed which version when, and the live gradual-rollout percentage split.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"script_name","type":"string","required":true,"description":"Worker script name (cf.list_workers returns it).","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_-]{0,63}$","max_length":64}}],"examples":[{"title":"Deployment history","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","script_name":"api-worker"}}],"search_terms":[]},{"id":"cf.zone_analytics","title":"Show zone HTTP analytics","summary":"Show a zone's HTTP traffic for the last N hours via the GraphQL analytics API — request, bandwidth, cached, threat, and unique-visitor totals plus the hourly series. Replaces the legacy /analytics/dashboard API, which Cloudflare sunset.","description":"Show a zone's HTTP traffic for the last N hours via the GraphQL analytics API — request, bandwidth, cached, threat, and unique-visitor totals plus the hourly series. Replaces the legacy /analytics/dashboard API, which Cloudflare sunset.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to report.","validation":{"min":1,"max":72}}],"examples":[{"title":"Last 24 hours","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.zone_details","title":"Show zone details","summary":"Show one zone's status, plan, nameservers, and activation state.","description":"Show one zone's status, plan, nameservers, and activation state.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Zone details","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.zone_settings","title":"List zone settings","summary":"List every zone-level setting — cache level, security level, SSL mode, minimum TLS version, development mode, Always Use HTTPS, and the rest.","description":"List every zone-level setting — cache level, security level, SSL mode, minimum TLS version, development mode, Always Use HTTPS, and the rest.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Settings","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]}]},{"version":"0.2.1","content_hash":"sha256:9ec2cb6c89b8e318dee1f78790b53caa91eae8cab61e19763aefdcb50c76a43c","tarball_url":"https://registry.emisar.dev/v1/packs/cloudflare/0.2.1/9ec2cb6c89b8e318dee1f78790b53caa91eae8cab61e19763aefdcb50c76a43c/pack.tar.gz","actions":[{"id":"cf.audit_logs","title":"List audit logs","summary":"List one bounded page of an account's Cloudflare audit log — who changed what through the dashboard and API, and when.","description":"List one bounded page of an account's Cloudflare audit log — who changed what through the dashboard and API, and when.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to read.","validation":{"min":1,"max":168}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Entries returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Last 24 hours","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.create_dns_record","title":"Create DNS record","summary":"Create one DNS record in a zone; a wrong name or content changes where live traffic and mail resolve as soon as caches expire.","description":"Create one DNS record in a zone; a wrong name or content changes where live traffic and mail resolve as soon as caches expire.","kind":"script","risk":"high","side_effects":["Resolvers pick up the new record as it propagates.","A proxied record routes its traffic through Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":true,"description":"Record type. SRV, CAA, and other data-object types are not supported by this action.","validation":{"enum":["A","AAAA","CNAME","TXT","MX","NS","PTR"]}},{"name":"name","type":"string","required":true,"description":"Record name as a FQDN (use the zone apex itself for root records). A leading \"*.\" makes it a wildcard.","validation":{"pattern":"^(\\*\\.)?([A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?\\.)*[A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?$","max_length":255}},{"name":"content","type":"string","required":true,"description":"Record content — an IP address, target hostname, or text value.","validation":{"pattern":"^[ -~]+$","max_length":2048}},{"name":"ttl","type":"integer","required":false,"default":1,"description":"TTL in seconds; 1 means automatic. Cloudflare rejects values between 2 and 59.","validation":{"min":1,"max":86400}},{"name":"proxied","type":"boolean","required":false,"default":false,"description":"Proxy A/AAAA/CNAME traffic through Cloudflare's edge. Ignored for other types."},{"name":"priority","type":"integer","required":false,"default":10,"description":"MX preference. Ignored for other types.","validation":{"min":0,"max":65535}},{"name":"comment","type":"string","required":false,"default":"","description":"Optional record comment.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Point a host at an IP","args":{"content":"203.0.113.20","name":"staging.example.com","proxied":true,"record_type":"A","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Add an SPF record","args":{"content":"v=spf1 include:_spf.example.com ~all","name":"example.com","record_type":"TXT","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.create_ip_access_rule","title":"Create IP access rule","summary":"Create a zone IP access rule that blocks, challenges, or allowlists an IP, CIDR range, ASN, or country; a wrong value can cut off legitimate visitors, and whitelist bypasses the zone's security checks for the match.","description":"Create a zone IP access rule that blocks, challenges, or allowlists an IP, CIDR range, ASN, or country; a wrong value can cut off legitimate visitors, and whitelist bypasses the zone's security checks for the match.","kind":"script","risk":"high","side_effects":["The rule applies at the edge within seconds.","whitelist exempts matching traffic from security checks."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":true,"description":"What to do with matching traffic.","validation":{"enum":["block","challenge","js_challenge","managed_challenge","whitelist"]}},{"name":"target","type":"string","required":true,"description":"What kind of value the rule matches.","validation":{"enum":["ip","ip_range","asn","country"]}},{"name":"value","type":"string","required":true,"description":"The IP address, CIDR range, AS number (AS13335), or two-letter country code to match.","validation":{"pattern":"^([0-9]{1,3}(\\.[0-9]{1,3}){3}(/([0-9]|[12][0-9]|3[012]))?|[0-9A-Fa-f:]{2,45}(/[0-9]{1,3})?|AS[0-9]{1,10}|[A-Z]{2})$","max_length":64}},{"name":"notes","type":"string","required":false,"default":"","description":"Optional note stored on the rule.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Block an attacking IP","args":{"mode":"block","notes":"SQLi attempts 2026-08-11","target":"ip","value":"198.51.100.99","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.create_worker_route","title":"Create Worker route","summary":"Create a zone Worker route that runs a script on matching URLs; a wrong pattern reroutes live traffic into Worker code. An empty script creates an exclusion route — matching requests bypass Workers and go to the origin.","description":"Create a zone Worker route that runs a script on matching URLs; a wrong pattern reroutes live traffic into Worker code. An empty script creates an exclusion route — matching requests bypass Workers and go to the origin.","kind":"script","risk":"high","side_effects":["Matching requests start executing the Worker (or bypassing Workers) within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pattern","type":"string","required":true,"description":"Route pattern, e.g. example.com/api/* — no scheme or query string.","validation":{"pattern":"^[A-Za-z0-9*.][A-Za-z0-9.*/_-]{0,511}$","max_length":512}},{"name":"script","type":"string","required":false,"default":"","description":"Worker script name to run, or empty to create a Workers-bypass route for the pattern.","validation":{"pattern":"^[A-Za-z0-9_-]{0,64}$","max_length":64}}],"examples":[{"title":"Route an API path to a Worker","args":{"pattern":"example.com/api/*","script":"api-worker","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Exclude a path from Workers","args":{"pattern":"example.com/webhooks/*","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_dns_record","title":"Delete DNS record","summary":"Delete one DNS record from a zone; whatever resolved through it stops resolving as caches expire, and the record cannot be restored except by recreating it.","description":"Delete one DNS record from a zone; whatever resolved through it stops resolving as caches expire, and the record cannot be restored except by recreating it.","kind":"script","risk":"high","side_effects":["The name stops resolving through this record as resolver caches expire."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_id","type":"string","required":true,"description":"DNS record ID (cf.dns_records returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Delete one record","args":{"record_id":"372e67954025e0ba6aaa6d586b9e0b59","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_ip_access_rule","title":"Delete IP access rule","summary":"Delete one zone IP access rule; removing a block re-admits the traffic it stopped, and removing a whitelist re-subjects that traffic to security checks.","description":"Delete one zone IP access rule; removing a block re-admits the traffic it stopped, and removing a whitelist re-subjects that traffic to security checks.","kind":"script","risk":"high","side_effects":["The rule stops applying at the edge within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"rule_id","type":"string","required":true,"description":"Access rule ID (cf.list_ip_access_rules returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Remove a rule","args":{"rule_id":"92f17202ed8bd63d69a66b86a49a8f6b","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.delete_worker_route","title":"Delete Worker route","summary":"Delete one zone Worker route; matching requests stop executing the Worker and fall through to other routes or the origin.","description":"Delete one zone Worker route; matching requests stop executing the Worker and fall through to other routes or the origin.","kind":"script","risk":"high","side_effects":["Matching requests stop hitting the Worker within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"route_id","type":"string","required":true,"description":"Route ID (cf.list_worker_routes returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Remove a route","args":{"route_id":"e7a57d8746e74ae49c25994dadb421b1","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dev_mode_off","title":"Disable development mode","summary":"End development mode early; the edge cache resumes serving immediately and origin load drops back to normal.","description":"End development mode early; the edge cache resumes serving immediately and origin load drops back to normal.","kind":"script","risk":"medium","side_effects":["Cache resumes serving from the edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode off","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dev_mode_on","title":"Enable development mode","summary":"Enable development mode for 3 hours — the zone's cache is bypassed and the origin receives every request, which can overload a busy origin.","description":"Enable development mode for 3 hours — the zone's cache is bypassed and the origin receives every request, which can overload a busy origin.","kind":"script","risk":"high","side_effects":["Cache is bypassed for 3 hours (auto-expires).","The origin gets every request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode on","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dns_analytics_report","title":"Show DNS analytics","summary":"Show a zone's DNS query analytics for the last N hours — query counts grouped by name, record type, and response code.","description":"Show a zone's DNS query analytics for the last N hours — query counts grouped by name, record type, and response code.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to report.","validation":{"min":1,"max":72}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Result rows returned.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top query names","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.dns_records","title":"List DNS records","summary":"List one bounded page of a zone's DNS records, optionally filtered by record type, name, or content.","description":"List one bounded page of a zone's DNS records, optionally filtered by record type, name, or content.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":false,"default":"","description":"Optional record type filter.","validation":{"enum":["","A","AAAA","CNAME","TXT","MX","NS","SRV","CAA","PTR"]}},{"name":"name","type":"string","required":false,"default":"","description":"Optional exact record name (FQDN) filter.","validation":{"pattern":"^[ -~]*$","max_length":255}},{"name":"content","type":"string","required":false,"default":"","description":"Optional exact record content filter.","validation":{"pattern":"^[ -~]*$","max_length":2048}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":100,"description":"Records returned in this page.","validation":{"min":5,"max":500}}],"examples":[{"title":"All records","args":{"zone_id":"abc123def456abc123def456abc123de"}},{"title":"A records for one name","args":{"name":"www.example.com","record_type":"A","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.firewall_rules","title":"List WAF custom rules","summary":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","description":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"WAF custom rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.lb_pool_health","title":"Show pool health","summary":"Show the latest per-location health-check results for one load balancer pool's origins — where an origin is failing and why.","description":"Show the latest per-location health-check results for one load balancer pool's origins — where an origin is failing and why.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pool_id","type":"string","required":true,"description":"Pool ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pool health","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","pool_id":"17b5962d775c646f3f9725cbc7a53df4"}}],"search_terms":[]},{"id":"cf.list_accounts","title":"List accounts","summary":"List one bounded page of Cloudflare accounts the API token can read — the account IDs the tunnel, load-balancer pool, and audit-log actions need.","description":"List one bounded page of Cloudflare accounts the API token can read — the account IDs the tunnel, load-balancer pool, and audit-log actions need.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Accounts returned in this page.","validation":{"min":5,"max":50}}],"examples":[{"title":"Accounts","args":{}}],"search_terms":[]},{"id":"cf.list_certificate_packs","title":"List certificate packs","summary":"List a zone's edge certificate packs with hostnames, validity, and expiry — the certificates Cloudflare serves for the zone. Contains no private keys.","description":"List a zone's edge certificate packs with hostnames, validity, and expiry — the certificates Cloudflare serves for the zone. Contains no private keys.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Certificate packs","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_ip_access_rules","title":"List IP access rules","summary":"List one bounded page of a zone's IP access rules — the block, challenge, and allowlist entries for IPs, CIDR ranges, ASNs, and countries.","description":"List one bounded page of a zone's IP access rules — the block, challenge, and allowlist entries for IPs, CIDR ranges, ASNs, and countries.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":false,"default":"","description":"Optional rule mode filter.","validation":{"enum":["","block","challenge","js_challenge","managed_challenge","whitelist"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Rules returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"All access rules","args":{"zone_id":"abc123def456abc123def456abc123de"}},{"title":"Blocks only","args":{"mode":"block","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_lb_pools","title":"List load balancer pools","summary":"List an account's load balancer origin pools with each pool's origins, weights, enabled state, and health.","description":"List an account's load balancer origin pools with each pool's origins, weights, enabled state, and health.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pools","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_load_balancers","title":"List load balancers","summary":"List a zone's load balancers with their pool assignments, steering policy, and proxy status.","description":"List a zone's load balancers with their pool assignments, steering policy, and proxy status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Load balancers","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_pages_projects","title":"List Pages projects","summary":"List one bounded page of an account's Cloudflare Pages projects with domains, production branch, and each project's latest deployment.","description":"List one bounded page of an account's Cloudflare Pages projects with domains, production branch, and each project's latest deployment.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Projects returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Projects","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_rulesets","title":"List zone rulesets","summary":"List every ruleset attached to a zone — WAF managed and custom rules, rate limiting, redirects, transforms — with each ruleset's phase and version.","description":"List every ruleset attached to a zone — WAF managed and custom rules, rate limiting, redirects, transforms — with each ruleset's phase and version.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Rulesets","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_tunnels","title":"List Cloudflare Tunnels","summary":"List one bounded page of an account's active cloudflared tunnels with each tunnel's health status and connection summary.","description":"List one bounded page of an account's active cloudflared tunnels with each tunnel's health status and connection summary.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID (cf.list_accounts returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Tunnels returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Tunnels","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_worker_routes","title":"List Worker routes","summary":"List a zone's Worker routes — which URL patterns run which Worker script.","description":"List a zone's Worker routes — which URL patterns run which Worker script.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Worker routes","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.list_workers","title":"List Worker scripts","summary":"List an account's deployed Worker scripts with creation and last-modified dates. Contains names and metadata only, never script code.","description":"List an account's deployed Worker scripts with creation and last-modified dates. Contains names and metadata only, never script code.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID (cf.list_accounts returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Workers","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0"}}],"search_terms":[]},{"id":"cf.list_zones","title":"List zones","summary":"List one bounded page of zones the API token can read, with each zone's ID, plan, status, and nameservers.","description":"List one bounded page of zones the API token can read, with each zone's ID, plan, status, and nameservers.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"name","type":"string","required":false,"default":"","description":"Optional exact zone name (domain) filter.","validation":{"pattern":"^(|[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?)*)$","max_length":253}},{"name":"status","type":"string","required":false,"default":"","description":"Optional zone status filter.","validation":{"enum":["","active","pending","initializing","moved","deactivated"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":50,"description":"Zones returned in this page.","validation":{"min":5,"max":50}}],"examples":[{"title":"First page","args":{}},{"title":"One zone by name","args":{"name":"example.com"}}],"search_terms":[]},{"id":"cf.page_rules","title":"List page rules","summary":"List a zone's legacy page rules with their URL patterns, actions, and status.","description":"List a zone's legacy page rules with their URL patterns, actions, and status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Page rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.pages_deployment_logs","title":"Show Pages build log","summary":"Show one Pages deployment's build log for failed-build triage. The log is arbitrary build output the project's own commands printed, so it can carry anything a build script echoes — treat it as sensitive diagnostics.","description":"Show one Pages deployment's build log for failed-build triage. The log is arbitrary build output the project's own commands printed, so it can carry anything a build script echoes — treat it as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Why the build failed","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"ccccdddd-eeee-4fff-8000-111122223333","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.pages_deployments","title":"List Pages deployments","summary":"List one bounded page of a Pages project's deployments — build status, environment, trigger, and commit — newest first, optionally filtered to production or preview.","description":"List one bounded page of a Pages project's deployments — build status, environment, trigger, and commit — newest first, optionally filtered to production or preview.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name (cf.list_pages_projects returns it).","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"environment","type":"string","required":false,"default":"","description":"Optional environment filter.","validation":{"enum":["","production","preview"]}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number.","validation":{"min":1,"max":2147483647}},{"name":"per_page","type":"integer","required":false,"default":25,"description":"Deployments returned in this page.","validation":{"min":5,"max":100}}],"examples":[{"title":"Recent production deploys","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","environment":"production","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.pause_zone","title":"Pause zone","summary":"Pause Cloudflare on a zone — traffic goes DNS-only, straight to the origin, losing the CDN cache, WAF, and DDoS protection while exposing the origin's real IPs.","description":"Pause Cloudflare on a zone — traffic goes DNS-only, straight to the origin, losing the CDN cache, WAF, and DDoS protection while exposing the origin's real IPs.","kind":"script","risk":"high","side_effects":["The origin serves all traffic directly and its IPs become visible.","WAF rules, IP access rules, and edge caching stop applying."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Pause","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_all_cache","title":"Purge entire zone cache","summary":"Purge ALL cached content for one zone; every URL misses to the origin at once, and on a busy zone that cold-cache spike can overload the origin.","description":"Purge ALL cached content for one zone; every URL misses to the origin at once, and on a busy zone that cold-cache spike can overload the origin.","kind":"script","risk":"critical","side_effects":["The origin sees a 100% miss rate until the cache re-warms.","Rate-limited by Cloudflare to roughly once per minute per zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Full purge","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_hostname","title":"Purge cached hostname","summary":"Purge every cached object for one hostname in a zone (Enterprise only); all of that host's traffic misses to the origin until the cache re-warms.","description":"Purge every cached object for one hostname in a zone (Enterprise only); all of that host's traffic misses to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request for the hostname until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hostname","type":"string","required":true,"description":"Hostname to purge.","validation":{"pattern":"^[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]{0,62}[A-Za-z0-9])?)*$","max_length":253}}],"examples":[{"title":"Purge one host","args":{"hostname":"assets.example.com","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_pages_build_cache","title":"Purge Pages build cache","summary":"Purge one Pages project's build cache; live traffic is untouched, and the next build resolves dependencies from scratch and runs slower.","description":"Purge one Pages project's build cache; live traffic is untouched, and the next build resolves dependencies from scratch and runs slower.","kind":"script","risk":"medium","side_effects":["The next deployment builds cold."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}}],"examples":[{"title":"Clear a poisoned build cache","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.purge_prefix","title":"Purge cached URL prefix","summary":"Purge every cached URL under one hostname/path prefix (Enterprise only); everything under the prefix misses to the origin until the cache re-warms.","description":"Purge every cached URL under one hostname/path prefix (Enterprise only); everything under the prefix misses to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request under the prefix until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"prefix","type":"string","required":true,"description":"Prefix to purge, written as hostname/path without a scheme or query string.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9.-]{0,252}/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*$","max_length":2048}}],"examples":[{"title":"Purge a path","args":{"prefix":"www.example.com/assets/","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_tag","title":"Purge cached tag","summary":"Purge every cached object carrying one Cache-Tag in a zone (Enterprise only); all tagged objects miss to the origin until the cache re-warms.","description":"Purge every cached object carrying one Cache-Tag in a zone (Enterprise only); all tagged objects miss to the origin until the cache re-warms.","kind":"script","risk":"high","side_effects":["The origin serves every request for tagged objects until the cache re-warms.","Requires a Cloudflare Enterprise zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"tag","type":"string","required":true,"description":"Cache-Tag value to purge.","validation":{"pattern":"^[A-Za-z0-9._:/=-]{1,200}$","max_length":200}}],"examples":[{"title":"Purge a release tag","args":{"tag":"release-2026-08-11","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.purge_url","title":"Purge cached URL","summary":"Purge one URL from a zone's edge cache; the next request for each purged variant reaches the origin and can increase origin load.","description":"Purge one URL from a zone's edge cache; the next request for each purged variant reaches the origin and can increase origin load.","kind":"script","risk":"high","side_effects":["Removes cached variants matching the requested URL.","Causes subsequent requests to miss until the object is cached again."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"url","type":"string","required":true,"sensitive":true,"description":"Absolute URL to purge. Query strings are sent to Cloudflare but redacted from the audit trail.","validation":{"pattern":"^https?://[A-Za-z0-9][A-Za-z0-9.-]{0,252}(:[0-9]{1,5})?/[A-Za-z0-9._~!$&'()*+,;=:@%/?-]*$","max_length":2048}}],"examples":[{"title":"Purge one asset","args":{"url":"https://example.com/style.css","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.retry_pages_deployment","title":"Retry Pages deployment","summary":"Re-run one Pages deployment's build; if it succeeds and is the newest production deployment, the rebuilt content goes live — retrying an old deployment can put stale content into production.","description":"Re-run one Pages deployment's build; if it succeeds and is the newest production deployment, the rebuilt content goes live — retrying an old deployment can put stale content into production.","kind":"script","risk":"high","side_effects":["A new build runs with that deployment's commit and settings.","A successful production retry becomes the live deployment."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Deployment to retry (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Retry the failed build","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"ccccdddd-eeee-4fff-8000-111122223333","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.rollback_pages_deployment","title":"Roll back Pages deployment","summary":"Roll a Pages project's production traffic back to an earlier deployment; the live site switches to that build's content immediately.","description":"Roll a Pages project's production traffic back to an earlier deployment; the live site switches to that build's content immediately.","kind":"script","risk":"high","side_effects":["Production serves the selected deployment's content within seconds.","Rolling back skips whatever the newer deployments shipped, including fixes."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"project_name","type":"string","required":true,"description":"Pages project name.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,57}$","max_length":58}},{"name":"deployment_id","type":"string","required":true,"description":"Production deployment to make live again (cf.pages_deployments returns it).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Back to the last good build","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","deployment_id":"bbbbcccc-dddd-4eee-8fff-000011112222","project_name":"marketing-site"}}],"search_terms":[]},{"id":"cf.set_always_use_https","title":"Set Always Use HTTPS","summary":"Turn a zone's Always Use HTTPS redirect on or off; off lets visitors stay on plain HTTP, and on breaks any resource that must be served over HTTP.","description":"Turn a zone's Always Use HTTPS redirect on or off; off lets visitors stay on plain HTTP, and on breaks any resource that must be served over HTTP.","kind":"script","risk":"high","side_effects":["on redirects every HTTP request to HTTPS at the edge.","off stops the redirect and permits plain-HTTP browsing."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"value","type":"string","required":true,"description":"Redirect state to apply.","validation":{"enum":["on","off"]}}],"examples":[{"title":"Force HTTPS","args":{"value":"on","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_lb_pool_enabled","title":"Enable or disable LB pool","summary":"Enable or disable one load balancer origin pool; disabling shifts its traffic to the remaining pools, and disabling the last healthy pool sends traffic to the fallback.","description":"Enable or disable one load balancer origin pool; disabling shifts its traffic to the remaining pools, and disabling the last healthy pool sends traffic to the fallback.","kind":"script","risk":"high","side_effects":["Load balancers steer traffic away from (or back to) the pool within seconds."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pool_id","type":"string","required":true,"description":"Pool ID (cf.list_lb_pools returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"enabled","type":"boolean","required":true,"description":"Whether the pool receives traffic."}],"examples":[{"title":"Drain a pool","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","enabled":false,"pool_id":"17b5962d775c646f3f9725cbc7a53df4"}}],"search_terms":[]},{"id":"cf.set_min_tls_version","title":"Set minimum TLS version","summary":"Set the minimum TLS version a zone accepts from visitors; raising it cuts off legacy clients, and lowering it re-admits protocol versions with known weaknesses.","description":"Set the minimum TLS version a zone accepts from visitors; raising it cuts off legacy clients, and lowering it re-admits protocol versions with known weaknesses.","kind":"script","risk":"high","side_effects":["Clients below the minimum fail their TLS handshake."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"version","type":"string","required":true,"description":"Minimum TLS version to accept.","validation":{"enum":["1.0","1.1","1.2","1.3"]}}],"examples":[{"title":"Require TLS 1.2","args":{"version":"1.2","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_security_level","title":"Set security level","summary":"Set a zone's security level, including I'm Under Attack mode; under_attack challenges every visitor, and lowering the level exposes the origin to more hostile traffic.","description":"Set a zone's security level, including I'm Under Attack mode; under_attack challenges every visitor, and lowering the level exposes the origin to more hostile traffic.","kind":"script","risk":"high","side_effects":["under_attack serves an interstitial challenge to every visitor, including API clients.","Lowering the level admits traffic the previous level challenged or blocked."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"level","type":"string","required":true,"description":"Security level to apply.","validation":{"enum":["essentially_off","low","medium","high","under_attack"]}}],"examples":[{"title":"Under attack","args":{"level":"under_attack","zone_id":"abc123def456abc123def456abc123de"}},{"title":"Back to medium","args":{"level":"medium","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.set_ssl_mode","title":"Set SSL mode","summary":"Set a zone's edge-to-origin SSL mode; a downgrade (full to flexible or off) sends visitor traffic to the origin unencrypted, and strict breaks the site if the origin certificate is invalid.","description":"Set a zone's edge-to-origin SSL mode; a downgrade (full to flexible or off) sends visitor traffic to the origin unencrypted, and strict breaks the site if the origin certificate is invalid.","kind":"script","risk":"high","side_effects":["flexible and off carry origin traffic over plain HTTP.","strict fails requests when the origin certificate is untrusted or expired."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"mode","type":"string","required":true,"description":"SSL mode to apply.","validation":{"enum":["off","flexible","full","strict"]}}],"examples":[{"title":"Full (strict)","args":{"mode":"strict","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.ssl_verification","title":"Show SSL verification status","summary":"Show edge certificate verification status for a zone's hostnames — what a browser will be served and whether validation is stuck.","description":"Show edge certificate verification status for a zone's hostnames — what a browser will be served and whether validation is stuck.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Verification status","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.tunnel_connections","title":"Show tunnel connections","summary":"Show one tunnel's active cloudflared connectors — client version, architecture, origin IP, and the edge locations each connection is landed on.","description":"Show one tunnel's active cloudflared connectors — client version, architecture, origin IP, and the edge locations each connection is landed on.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"tunnel_id","type":"string","required":true,"description":"Tunnel ID (UUID).","validation":{"pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"}}],"examples":[{"title":"Connector status","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","tunnel_id":"f70a3b21-9c86-4dcb-8d5e-1f2a3b4c5d6e"}}],"search_terms":[]},{"id":"cf.unpause_zone","title":"Unpause zone","summary":"Resume Cloudflare on a paused zone; proxied traffic returns to the edge and the CDN cache, WAF, and DDoS protection re-engage.","description":"Resume Cloudflare on a paused zone; proxied traffic returns to the edge and the CDN cache, WAF, and DDoS protection re-engage.","kind":"script","risk":"medium","side_effects":["Proxied traffic moves back through Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Unpause","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.update_dns_record","title":"Update DNS record","summary":"Change fields on one existing DNS record; a wrong content or proxy flip reroutes live traffic as soon as caches expire. Empty or zero arguments leave that field unchanged, and at least one field must change.","description":"Change fields on one existing DNS record; a wrong content or proxy flip reroutes live traffic as soon as caches expire. Empty or zero arguments leave that field unchanged, and at least one field must change.","kind":"script","risk":"high","side_effects":["Resolvers pick up the changed record as it propagates.","Flipping proxied moves traffic onto or off Cloudflare's edge."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_id","type":"string","required":true,"description":"DNS record ID (cf.dns_records returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"record_type","type":"string","required":false,"default":"","description":"New record type, or empty to leave unchanged.","validation":{"enum":["","A","AAAA","CNAME","TXT","MX","NS","PTR"]}},{"name":"name","type":"string","required":false,"default":"","description":"New record name (FQDN), or empty to leave unchanged.","validation":{"pattern":"^(|(\\*\\.)?([A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?\\.)*[A-Za-z0-9_]([A-Za-z0-9_-]{0,62}[A-Za-z0-9_])?)$","max_length":255}},{"name":"content","type":"string","required":false,"default":"","description":"New record content, or empty to leave unchanged.","validation":{"pattern":"^[ -~]*$","max_length":2048}},{"name":"ttl","type":"integer","required":false,"default":0,"description":"New TTL in seconds (1 means automatic), or 0 to leave unchanged.","validation":{"min":0,"max":86400}},{"name":"proxied","type":"string","required":false,"default":"","description":"New proxy state for A/AAAA/CNAME records, or empty to leave unchanged.","validation":{"enum":["","true","false"]}},{"name":"comment","type":"string","required":false,"default":"","description":"New record comment, or empty to leave unchanged.","validation":{"pattern":"^[ -~]*$","max_length":500}}],"examples":[{"title":"Repoint a record","args":{"content":"203.0.113.30","record_id":"372e67954025e0ba6aaa6d586b9e0b59","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.update_worker_route","title":"Update Worker route","summary":"Replace one Worker route's pattern and script; a wrong pattern or script reroutes live traffic, and an empty script turns the route into a Workers bypass for matching requests.","description":"Replace one Worker route's pattern and script; a wrong pattern or script reroutes live traffic, and an empty script turns the route into a Workers bypass for matching requests.","kind":"script","risk":"high","side_effects":["Matching requests switch to the new script (or bypass Workers) within seconds."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"route_id","type":"string","required":true,"description":"Route ID (cf.list_worker_routes returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"pattern","type":"string","required":true,"description":"Route pattern to apply — the update replaces the whole route, so pass the full intended pattern.","validation":{"pattern":"^[A-Za-z0-9*.][A-Za-z0-9.*/_-]{0,511}$","max_length":512}},{"name":"script","type":"string","required":false,"default":"","description":"Worker script name to run, or empty to detach Workers from the pattern.","validation":{"pattern":"^[A-Za-z0-9_-]{0,64}$","max_length":64}}],"examples":[{"title":"Point a route at a hotfix Worker","args":{"pattern":"example.com/api/*","route_id":"e7a57d8746e74ae49c25994dadb421b1","script":"api-worker-hotfix","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.worker_deployments","title":"Show Worker deployments","summary":"Show one Worker script's deployment history — who deployed which version when, and the live gradual-rollout percentage split.","description":"Show one Worker script's deployment history — who deployed which version when, and the live gradual-rollout percentage split.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"account_id","type":"string","required":true,"description":"Account ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"script_name","type":"string","required":true,"description":"Worker script name (cf.list_workers returns it).","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_-]{0,63}$","max_length":64}}],"examples":[{"title":"Deployment history","args":{"account_id":"9f8e7d6c5b4a39281706f5e4d3c2b1a0","script_name":"api-worker"}}],"search_terms":[]},{"id":"cf.zone_analytics","title":"Show zone HTTP analytics","summary":"Show a zone's HTTP traffic for the last N hours via the GraphQL analytics API — request, bandwidth, cached, threat, and unique-visitor totals plus the hourly series. Replaces the legacy /analytics/dashboard API, which Cloudflare sunset.","description":"Show a zone's HTTP traffic for the last N hours via the GraphQL analytics API — request, bandwidth, cached, threat, and unique-visitor totals plus the hourly series. Replaces the legacy /analytics/dashboard API, which Cloudflare sunset.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"hours","type":"integer","required":false,"default":24,"description":"How many hours back to report.","validation":{"min":1,"max":72}}],"examples":[{"title":"Last 24 hours","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.zone_details","title":"Show zone details","summary":"Show one zone's status, plan, nameservers, and activation state.","description":"Show one zone's status, plan, nameservers, and activation state.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Zone details","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]},{"id":"cf.zone_settings","title":"List zone settings","summary":"List every zone-level setting — cache level, security level, SSL mode, minimum TLS version, development mode, Always Use HTTPS, and the rest.","description":"List every zone-level setting — cache level, security level, SSL mode, minimum TLS version, development mode, Always Use HTTPS, and the rest.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Settings","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[]}]},{"version":"0.1.8","content_hash":"sha256:975ff79d8d3d93478eca502a88d91430f1ae2bd959f830e1d847f40139bb372d","tarball_url":"https://registry.emisar.dev/v1/packs/cloudflare/0.1.8/975ff79d8d3d93478eca502a88d91430f1ae2bd959f830e1d847f40139bb372d/pack.tar.gz","actions":[{"id":"cf.cache_settings","title":"GET /zones/<id>/settings","summary":"List all zone-level settings (cache TTL, security level, SSL mode, etc).","description":"List all zone-level settings (cache TTL, security level, SSL mode, etc).","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Settings","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones/${1}/settings\" -H @-","emisar","{{ args.zone_id }}"]}},{"id":"cf.dev_mode_off","title":"PATCH /zones/<id>/settings/development_mode (off)","summary":"End development mode early. Cache resumes normal behavior immediately.","description":"End development mode early. Cache resumes normal behavior immediately.","kind":"exec","risk":"medium","side_effects":["Cache resumes serving from edge — origin load drops back to normal."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode off","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPATCH \"https://api.cloudflare.com/client/v4/zones/${1}/settings/development_mode\" -H @- -H \"Content-Type: application/json\" -d '{\"value\":\"off\"}'","emisar","{{ args.zone_id }}"]}},{"id":"cf.dev_mode_on","title":"PATCH /zones/<id>/settings/development_mode","summary":"Enable development mode for 3 hours — bypasses caching for this zone.","description":"Enable development mode for 3 hours — bypasses caching for this zone.","kind":"exec","risk":"high","side_effects":["Cache is bypassed for 3 hours (auto-expires).","Origin gets every request."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Dev mode on","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPATCH \"https://api.cloudflare.com/client/v4/zones/${1}/settings/development_mode\" -H @- -H \"Content-Type: application/json\" -d '{\"value\":\"on\"}'","emisar","{{ args.zone_id }}"]}},{"id":"cf.dns_records","title":"GET /zones/<id>/dns_records","summary":"List all DNS records in one zone.","description":"List all DNS records in one zone.","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"DNS for one zone","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones/${1}/dns_records?per_page=200\" -H @-","emisar","{{ args.zone_id }}"]}},{"id":"cf.firewall_rules","title":"GET /zones/<id>/rulesets/phases/http_request_firewall_custom/entrypoint","summary":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","description":"List zone WAF custom rules — the entrypoint ruleset for the http_request_firewall_custom phase. Replaces the legacy /firewall/rules API, which Cloudflare sunset on 2025-06-15.","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Firewall rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones/${1}/rulesets/phases/http_request_firewall_custom/entrypoint\" -H @-","emisar","{{ args.zone_id }}"]}},{"id":"cf.list_zones","title":"GET /zones","summary":"List all zones accessible by the API token.","description":"List all zones accessible by the API token.","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[],"examples":[{"title":"Zones","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones?per_page=50\" -H @-"]}},{"id":"cf.page_rules","title":"GET /zones/<id>/pagerules","summary":"List all page rules for one zone.","description":"List all page rules for one zone.","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Page rules","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones/${1}/pagerules\" -H @-","emisar","{{ args.zone_id }}"]}},{"id":"cf.purge_all_cache","title":"POST /zones/<id>/purge_cache (everything)","summary":"Purge ALL cached content for one zone. Cold-cache origin spike — every URL becomes a miss until it warms again. Avoid on busy zones.","description":"Purge ALL cached content for one zone. Cold-cache origin spike — every URL becomes a miss until it warms again. Avoid on busy zones.","kind":"exec","risk":"critical","side_effects":["Origin sees a 100% miss rate until cache re-warms.","Rate-limited by Cloudflare to once per minute per zone."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Full purge","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPOST \"https://api.cloudflare.com/client/v4/zones/${1}/purge_cache\" -H @- -H \"Content-Type: application/json\" -d '{\"purge_everything\":true}'","emisar","{{ args.zone_id }}"]}},{"id":"cf.purge_url","title":"POST /zones/<id>/purge_cache (single URL)","summary":"Purge cache for one URL. Safe — only affects that URL's cached variants.","description":"Purge cache for one URL. Safe — only affects that URL's cached variants.","kind":"exec","risk":"high","side_effects":["Next request for that URL is a cache miss; hits origin."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}},{"name":"url","type":"string","required":true,"description":"Absolute URL to purge.","validation":{"pattern":"^https://[a-zA-Z0-9.\\-/]{1,512}$"}}],"examples":[{"title":"Purge one URL","args":{"url":"https://example.com/style.css","zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPOST \"https://api.cloudflare.com/client/v4/zones/${1}/purge_cache\" -H @- -H \"Content-Type: application/json\" -d '{\"files\":[\"'\"$2\"'\"]}'","emisar","{{ args.zone_id }}","{{ args.url }}"]}},{"id":"cf.zone_analytics","title":"GET /zones/<id>/analytics/dashboard","summary":"Show last-24h analytics for one zone (requests, bandwidth, threats).","description":"Show last-24h analytics for one zone (requests, bandwidth, threats).","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"24h analytics","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones/${1}/analytics/dashboard?since=-1440\" -H @-","emisar","{{ args.zone_id }}"]}},{"id":"cf.zone_details","title":"GET /zones/<id>","summary":"Show one zone's full settings + state + nameservers.","description":"Show one zone's full settings + state + nameservers.","kind":"exec","risk":"low","side_effects":["One API request.","Read-only."],"args":[{"name":"zone_id","type":"string","required":true,"description":"Zone ID.","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Zone details","args":{"zone_id":"abc123def456abc123def456abc123de"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CF_API_TOKEN\" ] && printf 'Authorization: Bearer %s\\n' \"$CF_API_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"https://api.cloudflare.com/client/v4/zones/${1}\" -H @-","emisar","{{ args.zone_id }}"]}}]}]},{"id":"cockroach","name":"CockroachDB","version":"0.1.9","description":"Investigate a CockroachDB cluster over the `cockroach` CLI — node liveness / store capacity, under-replicated & unavailable ranges, running queries / sessions / transactions, contention & locks, jobs, statement statistics, table sizes, and cluster settings — plus a few gated operators (cancel a query / session / job, pause / resume a job, decommission / recommission a node). Reads are SQL against crdb_internal / SHOW statements; mutators use SQL or `cockroach node`.","vendor":"emisar","homepage":"https://emisar.dev/packs/cockroach","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/cockroach","content_hash":"sha256:cba1b9fe3b7973bbc0b48bc260f06108e018509a2ca9efe96c2316425d4c8168","tarball_url":"https://registry.emisar.dev/v1/packs/cockroach/0.1.9/cba1b9fe3b7973bbc0b48bc260f06108e018509a2ca9efe96c2316425d4c8168/pack.tar.gz","requires":{"os":["linux"],"binaries":["cockroach"]},"detect":{"binaries":[],"processes":["cockroach"],"ports":[26257]},"setup":{"summary":"Every action expands `COCKROACH_URL` on the runner host and passes it to `cockroach` as --url, so host, port, database, TLS mode and the client cert/key paths all live in that single postgres-style URL.","env":[{"name":"COCKROACH_URL","required":true,"description":"Postgres-style CockroachDB connection URL. Use CLIENT-CERT auth (sslmode=verify-full + sslrootcert/sslcert/sslkey paths) — do NOT embed a password, since the URL is passed on the command line. The referenced key file is the secret; the URL itself carries only paths.","example":"postgresql://opsuser@db.internal:26257/defaultdb?sslmode=verify-full&sslrootcert=/certs/ca.crt&sslcert=/certs/client.opsuser.crt&sslkey=/certs/client.opsuser.key"}],"notes":["Create the SQL user, then mint its client cert with cockroach cert create-client <user> --certs-dir=<dir> --ca-key=<ca.key>; point sslcert and sslkey in `COCKROACH_URL` at the pair that writes.","`COCKROACH_URL` must be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so without it cockroach can't find the cluster.","Use client-cert auth in the URL (no embedded password): the URL appears in the action's command line / audit record, so a password there would leak. The client key file (referenced by path) stays on the host and is the actual credential.","The SQL user needs VIEWACTIVITY + VIEWCLUSTERMETADATA for the reads, and CANCELQUERY / CANCELSESSION / CONTROLJOB (or admin) for the matching mutators. node decommission/recommission need admin.","Reads use --format=tsv (parsed as text). There is no SQL surface for hot ranges, per-range QPS, replication lag, or clock offset — those live in the DB Console / Prometheus, so this pack deliberately omits them."],"verify":"cockroach.databases"},"actions":[{"id":"cockroach.cancel_job","title":"Cancel a job (CANCEL JOB)","summary":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","description":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","kind":"exec","risk":"medium","side_effects":["The target job is cancelled and begins reverting."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Cancel a job","args":{"job_id":891234567890123456}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.cancel_query","title":"Cancel a running query (CANCEL QUERY)","summary":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","description":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","kind":"exec","risk":"medium","side_effects":["The target query is cancelled with an error.","The session/connection stays open."],"args":[{"name":"query_id","type":"string","required":true,"description":"query_id from cockroach.cluster_queries.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a query","args":{"query_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL QUERY '${1}'\"","emisar","{{ args.query_id }}"]}},{"id":"cockroach.cancel_session","title":"Cancel a session (CANCEL SESSION)","summary":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","description":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","kind":"exec","risk":"medium","side_effects":["The target session is terminated and its connection closed.","Any open transaction on it is rolled back."],"args":[{"name":"session_id","type":"string","required":true,"description":"session_id from cockroach.cluster_sessions.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a session","args":{"session_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL SESSION '${1}'\"","emisar","{{ args.session_id }}"]}},{"id":"cockroach.cluster_queries","title":"Show running queries cluster-wide","summary":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","description":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_queries.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Oldest running queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT query_id, node_id, user_name, start, client_address, application_name, left(query,200) AS query FROM crdb_internal.cluster_queries ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_sessions","title":"Show open sessions cluster-wide","summary":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","description":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_sessions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT session_id, node_id, user_name, client_address, application_name, active_queries, session_start FROM crdb_internal.cluster_sessions ORDER BY session_start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_settings","title":"Show cluster settings","summary":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings. Credential values are masked in the output; the setting name stays visible so you can see it is set.","description":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings. Credential values are masked in the output; the setting name stays visible so you can see it is set.","kind":"exec","risk":"medium","side_effects":["One read-only SHOW CLUSTER SETTINGS query.","Read-only, but it returns the WHOLE cluster configuration.","CockroachDB does not mask these itself. On v26.2.4, SHOW CLUSTER SETTINGS prints server.oidc_authentication.client_secret in cleartext, and the runner's default rules do not match the TSV shape — measured, not assumed.","CockroachDB owns this key space, so its credential settings are enumerable rather than guessed at. Three of the 406 settings on v26.2.4 carry a secret value — server.oidc_authentication.client_secret, server.ldap_authentication.client.tls_key, and enterprise.license.","Every one of those ends in a suffix the redaction rule matches. The rule also masks server.oidc_authentication.claim_json_key, which is a claim NAME rather than a secret — an accepted over-mask, since a suffix match survives a vendor rename where an enumerated allowlist does not.","That established coverage is why this is medium rather than high, and why it is not low — a value reaching the model without approval must not be secret."],"args":[],"examples":[{"title":"All cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW CLUSTER SETTINGS\""]}},{"id":"cockroach.cluster_transactions","title":"Show open transactions cluster-wide","summary":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","description":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_transactions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open transactions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT id, node_id, session_id, start, application_name, num_stmts, num_retries FROM crdb_internal.cluster_transactions ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_events","title":"Show who is blocking whom (contention events)","summary":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","description":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.transaction_contention_events.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent contention","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT collection_ts, blocking_txn_id, waiting_txn_id, contention_duration, database_name, table_name, index_name, contending_pretty_key FROM crdb_internal.transaction_contention_events ORDER BY collection_ts DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_leaderboard","title":"Show most-contended objects","summary":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","description":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_contention_events.","Read-only."],"args":[],"examples":[{"title":"Contention leaderboard","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT table_id, index_id, num_contention_events, cumulative_contention_time FROM crdb_internal.cluster_contention_events ORDER BY cumulative_contention_time DESC LIMIT 50\""]}},{"id":"cockroach.databases","title":"List databases (SHOW DATABASES)","summary":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","description":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","kind":"exec","risk":"low","side_effects":["One SHOW DATABASES query.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW DATABASES\""]}},{"id":"cockroach.jobs","title":"Show recent / running jobs","summary":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","description":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.jobs.","Read-only."],"args":[{"name":"status","type":"string","required":false,"default":"","description":"Optional status filter (e.g. running, paused, failed); empty = all.","validation":{"pattern":"^[a-z-]{0,32}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent jobs","args":{}},{"title":"Running jobs only","args":{"status":"running"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT job_id, job_type, status, running_status, created, finished, fraction_completed, left(coalesce(description,''),120) AS description, left(coalesce(error,''),200) AS error FROM crdb_internal.jobs WHERE ('${1}' = '' OR status = '${1}') ORDER BY created DESC LIMIT {{ args.limit }}\"","emisar","{{ args.status }}"]}},{"id":"cockroach.locks","title":"Show contended locks (lock table)","summary":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","description":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_locks.","Read-only."],"args":[],"examples":[{"title":"Contended locks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, database_name, table_name, index_name, lock_key_pretty, txn_id, lock_strength, granted, contended, duration FROM crdb_internal.cluster_locks WHERE contended ORDER BY duration DESC LIMIT 100\""]}},{"id":"cockroach.node_decommission","title":"Decommission a node (cockroach node decommission)","summary":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","description":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","kind":"exec","risk":"high","side_effects":["The target node stops accepting new replicas and sheds its existing ones.","A fully decommissioned node cannot rejoin the cluster under the same id."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to decommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Begin decommissioning node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node decommission {{ args.node_id }} --wait=none --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_liveness","title":"Show node liveness / draining / decommissioning","summary":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","description":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.gossip_liveness.","Read-only."],"args":[],"examples":[{"title":"Liveness of all nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT node_id, epoch, draining, decommissioning, membership, updated_at FROM crdb_internal.gossip_liveness ORDER BY node_id\""]}},{"id":"cockroach.node_recommission","title":"Recommission a node (cockroach node recommission)","summary":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","description":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","kind":"exec","risk":"high","side_effects":["The node resumes accepting replicas."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to recommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Recommission node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node recommission {{ args.node_id }} --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_status","title":"Show node status (liveness, ranges, decommission, disk)","summary":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","description":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.node_status_one","title":"Show status for one node","summary":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","description":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Status for node 3","args":{"node_id":3}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status {{ args.node_id }} --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.pause_job","title":"Pause a job (PAUSE JOB)","summary":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","description":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","kind":"exec","risk":"medium","side_effects":["The target job is paused (resumable)."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Pause a job","args":{"job_id":891234567890123456}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"PAUSE JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.replication_constraints","title":"Show replication constraint violations","summary":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","description":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_constraint_stats.","Read-only."],"args":[],"examples":[{"title":"Constraint violations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT zone_id, subzone_id, type, config, violating_ranges, violation_start FROM system.replication_constraint_stats WHERE violating_ranges > 0 ORDER BY violating_ranges DESC\""]}},{"id":"cockroach.replication_stats","title":"Show under-replicated / unavailable range counts","summary":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","description":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_stats.","Read-only."],"args":[],"examples":[{"title":"Range health summary","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT coalesce(sum(total_ranges),0) AS total, coalesce(sum(under_replicated_ranges),0) AS under_replicated, coalesce(sum(unavailable_ranges),0) AS unavailable, coalesce(sum(over_replicated_ranges),0) AS over_replicated FROM system.replication_stats\""]}},{"id":"cockroach.resume_job","title":"Resume a paused job (RESUME JOB)","summary":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","description":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","kind":"exec","risk":"medium","side_effects":["The target job resumes running."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Resume a job","args":{"job_id":891234567890123456}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"RESUME JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.set_cluster_setting","title":"Set a cluster setting (SET CLUSTER SETTING)","summary":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","description":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","kind":"exec","risk":"critical","side_effects":["The named cluster setting is changed for the WHOLE cluster, immediately.","Rate-limit / GC / admission settings can throttle or destabilize the cluster.","Reversible with another set (or \"= DEFAULT\")."],"args":[{"name":"name","type":"string","required":true,"description":"Cluster setting name, e.g. kv.snapshot_rebalance.max_rate (see cockroach.cluster_settings).","validation":{"pattern":"^[a-z][a-z0-9._]{0,127}$","max_length":128}},{"name":"value","type":"string","required":true,"description":"The value in CockroachDB literal form — a bare number/boolean (100, true, DEFAULT) or a quoted string ('64 MiB', '24h'). Passed verbatim into the statement; bounded so it can't break out of its slot.","validation":{"pattern":"^('[A-Za-z0-9 ._:+/-]{1,254}'|[A-Za-z0-9._+-]{1,64})$","max_length":256}}],"examples":[{"title":"Raise the snapshot rebalance rate","args":{"name":"kv.snapshot_rebalance.max_rate","value":"'64 MiB'"}},{"title":"Reset a setting to its default","args":{"name":"kv.range_split.by_load_enabled","value":"DEFAULT"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET CLUSTER SETTING ${1} = ${2}\"","emisar","{{ args.name }}","{{ args.value }}"]}},{"id":"cockroach.statement_stats","title":"Show top statement fingerprints by exec count","summary":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","description":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.statement_statistics.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"Max fingerprints to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Busiest statements","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT app_name, (statistics->'statistics'->>'cnt')::INT AS count, (statistics->'statistics'->'svcLat'->>'mean')::FLOAT AS mean_svc_lat_s, left(metadata->>'query',200) AS query FROM crdb_internal.statement_statistics ORDER BY (statistics->'statistics'->>'cnt')::INT DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.store_status","title":"Show per-store disk capacity / range counts","summary":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","description":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.kv_store_status.","Read-only."],"args":[],"examples":[{"title":"Store capacity","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT node_id, store_id, capacity, available, used, logical_bytes, range_count, lease_count, writes_per_second FROM crdb_internal.kv_store_status ORDER BY node_id, store_id\""]}},{"id":"cockroach.table_ranges","title":"Show range count + size for one table","summary":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","description":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","kind":"exec","risk":"low","side_effects":["One read-only SHOW RANGES query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}}],"examples":[{"title":"Ranges of movr.rides","args":{"database":"movr","table":"rides"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, lease_holder, range_size_mb, replicas FROM [SHOW RANGES FROM TABLE ${1}.${2} WITH DETAILS]\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"cockroach.table_row_counts","title":"Show estimated row counts per table","summary":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","description":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.table_row_statistics.","Read-only."],"args":[],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT table_id, table_name, estimated_row_count FROM crdb_internal.table_row_statistics ORDER BY estimated_row_count DESC LIMIT 200\""]}}],"previous_versions":[{"version":"0.1.8","content_hash":"sha256:264dc0b2534d3d80674979b4b79213ce5e72b6d310bde13a382a95dba6562f23","tarball_url":"https://registry.emisar.dev/v1/packs/cockroach/0.1.8/264dc0b2534d3d80674979b4b79213ce5e72b6d310bde13a382a95dba6562f23/pack.tar.gz","actions":[{"id":"cockroach.cancel_job","title":"Cancel a job (CANCEL JOB)","summary":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","description":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","kind":"exec","risk":"medium","side_effects":["The target job is cancelled and begins reverting."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Cancel a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.cancel_query","title":"Cancel a running query (CANCEL QUERY)","summary":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","description":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","kind":"exec","risk":"medium","side_effects":["The target query is cancelled with an error.","The session/connection stays open."],"args":[{"name":"query_id","type":"string","required":true,"description":"query_id from cockroach.cluster_queries.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a query","args":{"query_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL QUERY '${1}'\"","emisar","{{ args.query_id }}"]}},{"id":"cockroach.cancel_session","title":"Cancel a session (CANCEL SESSION)","summary":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","description":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","kind":"exec","risk":"medium","side_effects":["The target session is terminated and its connection closed.","Any open transaction on it is rolled back."],"args":[{"name":"session_id","type":"string","required":true,"description":"session_id from cockroach.cluster_sessions.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a session","args":{"session_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL SESSION '${1}'\"","emisar","{{ args.session_id }}"]}},{"id":"cockroach.cluster_queries","title":"Show running queries cluster-wide","summary":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","description":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_queries.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Oldest running queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT query_id, node_id, user_name, start, client_address, application_name, left(query,200) AS query FROM crdb_internal.cluster_queries ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_sessions","title":"Show open sessions cluster-wide","summary":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","description":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_sessions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT session_id, node_id, user_name, client_address, application_name, active_queries, session_start FROM crdb_internal.cluster_sessions ORDER BY session_start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_settings","title":"Show cluster settings","summary":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings.","description":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings.","kind":"exec","risk":"low","side_effects":["One read-only SHOW CLUSTER SETTINGS query.","Read-only."],"args":[],"examples":[{"title":"All cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW CLUSTER SETTINGS\""]}},{"id":"cockroach.cluster_transactions","title":"Show open transactions cluster-wide","summary":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","description":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_transactions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open transactions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT id, node_id, session_id, start, application_name, num_stmts, num_retries FROM crdb_internal.cluster_transactions ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_events","title":"Show who is blocking whom (contention events)","summary":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","description":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.transaction_contention_events.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent contention","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT collection_ts, blocking_txn_id, waiting_txn_id, contention_duration, database_name, table_name, index_name, contending_pretty_key FROM crdb_internal.transaction_contention_events ORDER BY collection_ts DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_leaderboard","title":"Show most-contended objects","summary":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","description":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_contention_events.","Read-only."],"args":[],"examples":[{"title":"Contention leaderboard","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT table_id, index_id, num_contention_events, cumulative_contention_time FROM crdb_internal.cluster_contention_events ORDER BY cumulative_contention_time DESC LIMIT 50\""]}},{"id":"cockroach.databases","title":"List databases (SHOW DATABASES)","summary":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","description":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","kind":"exec","risk":"low","side_effects":["One SHOW DATABASES query.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW DATABASES\""]}},{"id":"cockroach.jobs","title":"Show recent / running jobs","summary":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","description":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.jobs.","Read-only."],"args":[{"name":"status","type":"string","required":false,"default":"","description":"Optional status filter (e.g. running, paused, failed); empty = all.","validation":{"pattern":"^[a-z-]{0,32}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent jobs","args":{}},{"title":"Running jobs only","args":{"status":"running"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT job_id, job_type, status, running_status, created, finished, fraction_completed, left(coalesce(description,''),120) AS description, left(coalesce(error,''),200) AS error FROM crdb_internal.jobs WHERE ('${1}' = '' OR status = '${1}') ORDER BY created DESC LIMIT {{ args.limit }}\"","emisar","{{ args.status }}"]}},{"id":"cockroach.locks","title":"Show contended locks (lock table)","summary":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","description":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_locks.","Read-only."],"args":[],"examples":[{"title":"Contended locks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, database_name, table_name, index_name, lock_key_pretty, txn_id, lock_strength, granted, contended, duration FROM crdb_internal.cluster_locks WHERE contended ORDER BY duration DESC LIMIT 100\""]}},{"id":"cockroach.node_decommission","title":"Decommission a node (cockroach node decommission)","summary":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","description":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","kind":"exec","risk":"high","side_effects":["The target node stops accepting new replicas and sheds its existing ones.","A fully decommissioned node cannot rejoin the cluster under the same id."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to decommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Begin decommissioning node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node decommission {{ args.node_id }} --wait=none --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_liveness","title":"Show node liveness / draining / decommissioning","summary":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","description":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.gossip_liveness.","Read-only."],"args":[],"examples":[{"title":"Liveness of all nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT node_id, epoch, draining, decommissioning, membership, updated_at FROM crdb_internal.gossip_liveness ORDER BY node_id\""]}},{"id":"cockroach.node_recommission","title":"Recommission a node (cockroach node recommission)","summary":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","description":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","kind":"exec","risk":"high","side_effects":["The node resumes accepting replicas."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to recommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Recommission node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node recommission {{ args.node_id }} --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_status","title":"Show node status (liveness, ranges, decommission, disk)","summary":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","description":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.node_status_one","title":"Show status for one node","summary":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","description":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Status for node 3","args":{"node_id":3}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status {{ args.node_id }} --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.pause_job","title":"Pause a job (PAUSE JOB)","summary":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","description":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","kind":"exec","risk":"medium","side_effects":["The target job is paused (resumable)."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Pause a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"PAUSE JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.replication_constraints","title":"Show replication constraint violations","summary":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","description":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_constraint_stats.","Read-only."],"args":[],"examples":[{"title":"Constraint violations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT zone_id, subzone_id, type, config, violating_ranges, violation_start FROM system.replication_constraint_stats WHERE violating_ranges > 0 ORDER BY violating_ranges DESC\""]}},{"id":"cockroach.replication_stats","title":"Show under-replicated / unavailable range counts","summary":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","description":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_stats.","Read-only."],"args":[],"examples":[{"title":"Range health summary","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT coalesce(sum(total_ranges),0) AS total, coalesce(sum(under_replicated_ranges),0) AS under_replicated, coalesce(sum(unavailable_ranges),0) AS unavailable, coalesce(sum(over_replicated_ranges),0) AS over_replicated FROM system.replication_stats\""]}},{"id":"cockroach.resume_job","title":"Resume a paused job (RESUME JOB)","summary":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","description":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","kind":"exec","risk":"medium","side_effects":["The target job resumes running."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Resume a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"RESUME JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.set_cluster_setting","title":"Set a cluster setting (SET CLUSTER SETTING)","summary":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","description":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","kind":"exec","risk":"critical","side_effects":["The named cluster setting is changed for the WHOLE cluster, immediately.","Rate-limit / GC / admission settings can throttle or destabilize the cluster.","Reversible with another set (or \"= DEFAULT\")."],"args":[{"name":"name","type":"string","required":true,"description":"Cluster setting name, e.g. kv.snapshot_rebalance.max_rate (see cockroach.cluster_settings).","validation":{"pattern":"^[a-z][a-z0-9._]{0,127}$","max_length":128}},{"name":"value","type":"string","required":true,"description":"The value in CockroachDB literal form — a bare number/boolean (100, true, DEFAULT) or a quoted string ('64 MiB', '24h'). Passed verbatim into the statement; bounded so it can't break out of its slot.","validation":{"pattern":"^('[A-Za-z0-9 ._:+/-]{1,254}'|[A-Za-z0-9._+-]{1,64})$","max_length":256}}],"examples":[{"title":"Raise the snapshot rebalance rate","args":{"name":"kv.snapshot_rebalance.max_rate","value":"'64 MiB'"}},{"title":"Reset a setting to its default","args":{"name":"kv.range_split.by_load_enabled","value":"DEFAULT"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET CLUSTER SETTING ${1} = ${2}\"","emisar","{{ args.name }}","{{ args.value }}"]}},{"id":"cockroach.statement_stats","title":"Show top statement fingerprints by exec count","summary":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","description":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.statement_statistics.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"Max fingerprints to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Busiest statements","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT app_name, (statistics->'statistics'->>'cnt')::INT AS count, (statistics->'statistics'->'svcLat'->>'mean')::FLOAT AS mean_svc_lat_s, left(metadata->>'query',200) AS query FROM crdb_internal.statement_statistics ORDER BY (statistics->'statistics'->>'cnt')::INT DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.store_status","title":"Show per-store disk capacity / range counts","summary":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","description":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.kv_store_status.","Read-only."],"args":[],"examples":[{"title":"Store capacity","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT node_id, store_id, capacity, available, used, logical_bytes, range_count, lease_count, writes_per_second FROM crdb_internal.kv_store_status ORDER BY node_id, store_id\""]}},{"id":"cockroach.table_ranges","title":"Show range count + size for one table","summary":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","description":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","kind":"exec","risk":"low","side_effects":["One read-only SHOW RANGES query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}}],"examples":[{"title":"Ranges of movr.rides","args":{"database":"movr","table":"rides"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, lease_holder, range_size_mb, replicas FROM [SHOW RANGES FROM TABLE ${1}.${2} WITH DETAILS]\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"cockroach.table_row_counts","title":"Show estimated row counts per table","summary":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","description":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.table_row_statistics.","Read-only."],"args":[],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT table_id, table_name, estimated_row_count FROM crdb_internal.table_row_statistics ORDER BY estimated_row_count DESC LIMIT 200\""]}}]},{"version":"0.1.5","content_hash":"sha256:70957debfd8131c6ad6b3f552222458e4d67f7061b3c18027155cf8fb4e248d1","tarball_url":"https://registry.emisar.dev/v1/packs/cockroach/0.1.5/70957debfd8131c6ad6b3f552222458e4d67f7061b3c18027155cf8fb4e248d1/pack.tar.gz","actions":[{"id":"cockroach.cancel_job","title":"Cancel a job (CANCEL JOB)","summary":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","description":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","kind":"exec","risk":"medium","side_effects":["The target job is cancelled and begins reverting."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Cancel a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.cancel_query","title":"Cancel a running query (CANCEL QUERY)","summary":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","description":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","kind":"exec","risk":"medium","side_effects":["The target query is cancelled with an error.","The session/connection stays open."],"args":[{"name":"query_id","type":"string","required":true,"description":"query_id from cockroach.cluster_queries.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a query","args":{"query_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL QUERY '${1}'\"","emisar","{{ args.query_id }}"]}},{"id":"cockroach.cancel_session","title":"Cancel a session (CANCEL SESSION)","summary":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","description":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","kind":"exec","risk":"medium","side_effects":["The target session is terminated and its connection closed.","Any open transaction on it is rolled back."],"args":[{"name":"session_id","type":"string","required":true,"description":"session_id from cockroach.cluster_sessions.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a session","args":{"session_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL SESSION '${1}'\"","emisar","{{ args.session_id }}"]}},{"id":"cockroach.cluster_queries","title":"Show running queries cluster-wide","summary":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","description":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_queries.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Oldest running queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT query_id, node_id, user_name, start, client_address, application_name, left(query,200) AS query FROM crdb_internal.cluster_queries ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_sessions","title":"Show open sessions cluster-wide","summary":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","description":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_sessions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT session_id, node_id, user_name, client_address, application_name, active_queries, session_start FROM crdb_internal.cluster_sessions ORDER BY session_start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_settings","title":"Show cluster settings","summary":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings.","description":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings.","kind":"exec","risk":"low","side_effects":["One read-only SHOW CLUSTER SETTINGS query.","Read-only."],"args":[],"examples":[{"title":"All cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW CLUSTER SETTINGS\""]}},{"id":"cockroach.cluster_transactions","title":"Show open transactions cluster-wide","summary":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","description":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_transactions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open transactions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT id, node_id, session_id, start, application_name, num_stmts, num_retries FROM crdb_internal.cluster_transactions ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_events","title":"Show who is blocking whom (contention events)","summary":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","description":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.transaction_contention_events.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent contention","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT collection_ts, blocking_txn_id, waiting_txn_id, contention_duration, database_name, table_name, index_name, contending_pretty_key FROM crdb_internal.transaction_contention_events ORDER BY collection_ts DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_leaderboard","title":"Show most-contended objects","summary":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","description":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_contention_events.","Read-only."],"args":[],"examples":[{"title":"Contention leaderboard","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT table_id, index_id, num_contention_events, cumulative_contention_time FROM crdb_internal.cluster_contention_events ORDER BY cumulative_contention_time DESC LIMIT 50\""]}},{"id":"cockroach.databases","title":"List databases (SHOW DATABASES)","summary":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","description":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","kind":"exec","risk":"low","side_effects":["One SHOW DATABASES query.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW DATABASES\""]}},{"id":"cockroach.jobs","title":"Show recent / running jobs","summary":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","description":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.jobs.","Read-only."],"args":[{"name":"status","type":"string","required":false,"default":"","description":"Optional status filter (e.g. running, paused, failed); empty = all.","validation":{"pattern":"^[a-z-]{0,32}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent jobs","args":{}},{"title":"Running jobs only","args":{"status":"running"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT job_id, job_type, status, running_status, created, finished, fraction_completed, left(coalesce(description,''),120) AS description, left(coalesce(error,''),200) AS error FROM crdb_internal.jobs WHERE ('${1}' = '' OR status = '${1}') ORDER BY created DESC LIMIT {{ args.limit }}\"","emisar","{{ args.status }}"]}},{"id":"cockroach.locks","title":"Show contended locks (lock table)","summary":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","description":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_locks.","Read-only."],"args":[],"examples":[{"title":"Contended locks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, database_name, table_name, index_name, lock_key_pretty, txn_id, lock_strength, granted, contended, duration FROM crdb_internal.cluster_locks WHERE contended ORDER BY duration DESC LIMIT 100\""]}},{"id":"cockroach.node_decommission","title":"Decommission a node (cockroach node decommission)","summary":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","description":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","kind":"exec","risk":"high","side_effects":["The target node stops accepting new replicas and sheds its existing ones.","A fully decommissioned node cannot rejoin the cluster under the same id."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to decommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Begin decommissioning node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node decommission {{ args.node_id }} --wait=none --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_liveness","title":"Show node liveness / draining / decommissioning","summary":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","description":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.gossip_liveness.","Read-only."],"args":[],"examples":[{"title":"Liveness of all nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT node_id, epoch, draining, decommissioning, membership, updated_at FROM crdb_internal.gossip_liveness ORDER BY node_id\""]}},{"id":"cockroach.node_recommission","title":"Recommission a node (cockroach node recommission)","summary":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","description":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","kind":"exec","risk":"high","side_effects":["The node resumes accepting replicas."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to recommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Recommission node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node recommission {{ args.node_id }} --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_status","title":"Show node status (liveness, ranges, decommission, disk)","summary":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","description":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.node_status_one","title":"Show status for one node","summary":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","description":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Status for node 3","args":{"node_id":3}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status {{ args.node_id }} --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.pause_job","title":"Pause a job (PAUSE JOB)","summary":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","description":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","kind":"exec","risk":"medium","side_effects":["The target job is paused (resumable)."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Pause a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"PAUSE JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.replication_constraints","title":"Show replication constraint violations","summary":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","description":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_constraint_stats.","Read-only."],"args":[],"examples":[{"title":"Constraint violations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT zone_id, subzone_id, type, config, violating_ranges, violation_start FROM system.replication_constraint_stats WHERE violating_ranges > 0 ORDER BY violating_ranges DESC\""]}},{"id":"cockroach.replication_stats","title":"Show under-replicated / unavailable range counts","summary":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","description":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_stats.","Read-only."],"args":[],"examples":[{"title":"Range health summary","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT coalesce(sum(total_ranges),0) AS total, coalesce(sum(under_replicated_ranges),0) AS under_replicated, coalesce(sum(unavailable_ranges),0) AS unavailable, coalesce(sum(over_replicated_ranges),0) AS over_replicated FROM system.replication_stats\""]}},{"id":"cockroach.resume_job","title":"Resume a paused job (RESUME JOB)","summary":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","description":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","kind":"exec","risk":"medium","side_effects":["The target job resumes running."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Resume a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"RESUME JOB ${1}\"","emisar","{{ args.job_id }}"]}},{"id":"cockroach.set_cluster_setting","title":"Set a cluster setting (SET CLUSTER SETTING)","summary":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","description":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","kind":"exec","risk":"critical","side_effects":["The named cluster setting is changed for the WHOLE cluster, immediately.","Rate-limit / GC / admission settings can throttle or destabilize the cluster.","Reversible with another set (or \"= DEFAULT\")."],"args":[{"name":"name","type":"string","required":true,"description":"Cluster setting name, e.g. kv.snapshot_rebalance.max_rate (see cockroach.cluster_settings).","validation":{"pattern":"^[a-z][a-z0-9._]{0,127}$","max_length":128}},{"name":"value","type":"string","required":true,"description":"The value in CockroachDB literal form — a bare number/boolean (100, true, DEFAULT) or a quoted string ('64 MiB', '24h'). Passed verbatim into the statement; bounded so it can't break out of its slot.","validation":{"pattern":"^('[A-Za-z0-9 ._:+/-]{1,254}'|[A-Za-z0-9._+-]{1,64})$","max_length":256}}],"examples":[{"title":"Raise the snapshot rebalance rate","args":{"name":"kv.snapshot_rebalance.max_rate","value":"'64 MiB'"}},{"title":"Reset a setting to its default","args":{"name":"kv.range_split.by_load_enabled","value":"DEFAULT"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET CLUSTER SETTING ${1} = ${2}\"","emisar","{{ args.name }}","{{ args.value }}"]}},{"id":"cockroach.statement_stats","title":"Show top statement fingerprints by exec count","summary":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","description":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.statement_statistics.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"Max fingerprints to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Busiest statements","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT app_name, (statistics->'statistics'->>'cnt')::INT AS count, (statistics->'statistics'->'svcLat'->>'mean')::FLOAT AS mean_svc_lat_s, left(metadata->>'query',200) AS query FROM crdb_internal.statement_statistics ORDER BY (statistics->'statistics'->>'cnt')::INT DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.store_status","title":"Show per-store disk capacity / range counts","summary":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","description":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.kv_store_status.","Read-only."],"args":[],"examples":[{"title":"Store capacity","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT node_id, store_id, capacity, available, used, logical_bytes, range_count, lease_count, writes_per_second FROM crdb_internal.kv_store_status ORDER BY node_id, store_id\""]}},{"id":"cockroach.table_ranges","title":"Show range count + size for one table","summary":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","description":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","kind":"exec","risk":"low","side_effects":["One read-only SHOW RANGES query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}}],"examples":[{"title":"Ranges of movr.rides","args":{"database":"movr","table":"rides"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, lease_holder, range_size_mb, replicas FROM [SHOW RANGES FROM TABLE ${1}.${2} WITH DETAILS]\"","emisar","{{ args.database }}","{{ args.table }}"]}},{"id":"cockroach.table_row_counts","title":"Show estimated row counts per table","summary":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","description":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.table_row_statistics.","Read-only."],"args":[],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET allow_unsafe_internals = true; SELECT table_id, table_name, estimated_row_count FROM crdb_internal.table_row_statistics ORDER BY estimated_row_count DESC LIMIT 200\""]}}]},{"version":"0.1.3","content_hash":"sha256:b93cef9ed8802036877f0ee17a3c99a886671edf4a35b662202677f676b295f9","tarball_url":"https://registry.emisar.dev/v1/packs/cockroach/0.1.3/b93cef9ed8802036877f0ee17a3c99a886671edf4a35b662202677f676b295f9/pack.tar.gz","actions":[{"id":"cockroach.cancel_job","title":"Cancel a job (CANCEL JOB)","summary":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","description":"Cancel one job by id (from jobs). The job stops and rolls back any partial work where applicable. Use to abort a wrong or stuck schema change / backup / import.","kind":"exec","risk":"medium","side_effects":["The target job is cancelled and begins reverting."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Cancel a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL JOB {{ args.job_id }}\""]}},{"id":"cockroach.cancel_query","title":"Cancel a running query (CANCEL QUERY)","summary":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","description":"Stop one in-flight query by its query_id (from cluster_queries). The query ends with an error; the session/connection stays open. Use to kill a runaway query without dropping the client.","kind":"exec","risk":"medium","side_effects":["The target query is cancelled with an error.","The session/connection stays open."],"args":[{"name":"query_id","type":"string","required":true,"description":"query_id from cockroach.cluster_queries.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a query","args":{"query_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL QUERY '{{ args.query_id }}'\""]}},{"id":"cockroach.cancel_session","title":"Cancel a session (CANCEL SESSION)","summary":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","description":"End one client session by its session_id (from cluster_sessions) — its current query is cancelled and the connection closed; an open transaction is rolled back. Use to evict a stuck or abusive connection.","kind":"exec","risk":"medium","side_effects":["The target session is terminated and its connection closed.","Any open transaction on it is rolled back."],"args":[{"name":"session_id","type":"string","required":true,"description":"session_id from cockroach.cluster_sessions.","validation":{"pattern":"^[0-9a-f]{16,40}$"}}],"examples":[{"title":"Cancel a session","args":{"session_id":"16f8c5a0b2c3d4e50000000000000001"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"CANCEL SESSION '{{ args.session_id }}'\""]}},{"id":"cockroach.cluster_queries","title":"Show running queries cluster-wide","summary":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","description":"Show in-flight queries across all nodes (the SHOW CLUSTER QUERIES surface) — query id, node, user, start time, client address, application, and the query text (truncated). Use to find a long-running or runaway query.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_queries.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Oldest running queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT query_id, node_id, user_name, start, client_address, application_name, left(query,200) AS query FROM crdb_internal.cluster_queries ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_sessions","title":"Show open sessions cluster-wide","summary":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","description":"Show open SQL sessions across all nodes (the SHOW CLUSTER SESSIONS surface) — session id, node, user, client address, application, active queries, and session start. Use to see who is connected and from where.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_sessions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT session_id, node_id, user_name, client_address, application_name, active_queries, session_start FROM crdb_internal.cluster_sessions ORDER BY session_start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.cluster_settings","title":"Show cluster settings","summary":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings.","description":"Show all cluster settings with their current value, type, and description (SHOW CLUSTER SETTINGS). Use to confirm a setting's value during an investigation. Read-only — this pack does not change settings.","kind":"exec","risk":"low","side_effects":["One read-only SHOW CLUSTER SETTINGS query.","Read-only."],"args":[],"examples":[{"title":"All cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW CLUSTER SETTINGS\""]}},{"id":"cockroach.cluster_transactions","title":"Show open transactions cluster-wide","summary":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","description":"Show open transactions across all nodes — id, node, session, start time, application, statement count, and retry count, from crdb_internal.cluster_transactions. Use to spot long-open or heavily-retried transactions.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_transactions.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Max rows to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Open transactions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT id, node_id, session_id, start, application_name, num_stmts, num_retries FROM crdb_internal.cluster_transactions ORDER BY start ASC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_events","title":"Show who is blocking whom (contention events)","summary":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","description":"Show recent transaction-contention events — blocking vs waiting txn, how long the wait was, and the object (database / table / index) and key contended, from crdb_internal.transaction_contention_events. The core \"what's blocking my writes\" view.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.transaction_contention_events.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent contention","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT collection_ts, blocking_txn_id, waiting_txn_id, contention_duration, database_name, table_name, index_name, contending_pretty_key FROM crdb_internal.transaction_contention_events ORDER BY collection_ts DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.contention_leaderboard","title":"Show most-contended objects","summary":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","description":"Show the most-contended tables/indexes by cumulative contention time, from crdb_internal.cluster_contention_events. Use to find the hotspot behind widespread contention.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_contention_events.","Read-only."],"args":[],"examples":[{"title":"Contention leaderboard","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT table_id, index_id, num_contention_events, cumulative_contention_time FROM crdb_internal.cluster_contention_events ORDER BY cumulative_contention_time DESC LIMIT 50\""]}},{"id":"cockroach.databases","title":"List databases (SHOW DATABASES)","summary":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","description":"List the cluster's databases. Cheap connectivity + auth check, and the pack's verify action.","kind":"exec","risk":"low","side_effects":["One SHOW DATABASES query.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SHOW DATABASES\""]}},{"id":"cockroach.jobs","title":"Show recent / running jobs","summary":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","description":"Show cluster jobs (schema changes, backups, restores, imports, row-TTL) from crdb_internal.jobs — id, type, status, running status, timing, fraction complete, description, and any error. Optionally filter by status. Use to find a stuck or failed job.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.jobs.","Read-only."],"args":[{"name":"status","type":"string","required":false,"default":"","description":"Optional status filter (e.g. running, paused, failed); empty = all.","validation":{"pattern":"^[a-z-]{0,32}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max rows to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Recent jobs","args":{}},{"title":"Running jobs only","args":{"status":"running"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT job_id, job_type, status, running_status, created, finished, fraction_completed, left(coalesce(description,''),120) AS description, left(coalesce(error,''),200) AS error FROM crdb_internal.jobs WHERE ('{{ args.status }}' = '' OR status = '{{ args.status }}') ORDER BY created DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.locks","title":"Show contended locks (lock table)","summary":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","description":"Show contended entries in the lock table — range, object, the pretty key, holding txn, lock strength, and how long it's been held, from crdb_internal.cluster_locks. Use to find the lock behind a stall.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.cluster_locks.","Read-only."],"args":[],"examples":[{"title":"Contended locks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, database_name, table_name, index_name, lock_key_pretty, txn_id, lock_strength, granted, contended, duration FROM crdb_internal.cluster_locks WHERE contended ORDER BY duration DESC LIMIT 100\""]}},{"id":"cockroach.node_decommission","title":"Decommission a node (cockroach node decommission)","summary":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","description":"Mark one node decommissioning and start moving its replicas off. Effectively irreversible once it completes — a fully decommissioned node cannot rejoin under the same id. Uses --wait=none, so the call returns after initiating; track progress with node_status.","kind":"exec","risk":"high","side_effects":["The target node stops accepting new replicas and sheds its existing ones.","A fully decommissioned node cannot rejoin the cluster under the same id."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to decommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Begin decommissioning node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node decommission {{ args.node_id }} --wait=none --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_liveness","title":"Show node liveness / draining / decommissioning","summary":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","description":"Show per-node liveness from crdb_internal.gossip_liveness — epoch, draining, decommissioning, membership, and last update. Use to see which nodes are live and which are leaving the cluster.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.gossip_liveness.","Read-only."],"args":[],"examples":[{"title":"Liveness of all nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT node_id, epoch, draining, decommissioning, membership, updated_at FROM crdb_internal.gossip_liveness ORDER BY node_id\""]}},{"id":"cockroach.node_recommission","title":"Recommission a node (cockroach node recommission)","summary":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","description":"Reverse an in-progress decommission so the node resumes accepting replicas. Only valid before the decommission completes. Use to abort a decommission started by mistake.","kind":"exec","risk":"high","side_effects":["The node resumes accepting replicas."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id to recommission (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Recommission node 4","args":{"node_id":4}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node recommission {{ args.node_id }} --url \"$COCKROACH_URL\""]}},{"id":"cockroach.node_status","title":"Show node status (liveness, ranges, decommission, disk)","summary":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","description":"Show every node's status — address, build, liveness, replica/leaseholder counts, range counts (incl. unavailable / under-replicated), liveness bytes, and decommission / draining / membership state. The first stop for cluster health.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.node_status_one","title":"Show status for one node","summary":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","description":"Show full status for a single node by id — same columns as node_status, scoped to one node. Use to inspect a node flagged elsewhere.","kind":"exec","risk":"low","side_effects":["One `cockroach node status` call.","Read-only."],"args":[{"name":"node_id","type":"integer","required":true,"description":"Node id (from node_status).","validation":{"min":1,"max":65535}}],"examples":[{"title":"Status for node 3","args":{"node_id":3}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach node status {{ args.node_id }} --all --url \"$COCKROACH_URL\" --format=tsv"]}},{"id":"cockroach.pause_job","title":"Pause a job (PAUSE JOB)","summary":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","description":"Pause one running job by id (from jobs). It can be resumed later with resume_job. Use to relieve load from a heavy backup / schema change without losing its progress.","kind":"exec","risk":"medium","side_effects":["The target job is paused (resumable)."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Pause a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"PAUSE JOB {{ args.job_id }}\""]}},{"id":"cockroach.replication_constraints","title":"Show replication constraint violations","summary":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","description":"Show zones whose ranges violate their replication constraints (e.g. a region/locality requirement that can't be met), from system.replication_constraint_stats. Empty means all constraints satisfied.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_constraint_stats.","Read-only."],"args":[],"examples":[{"title":"Constraint violations","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT zone_id, subzone_id, type, config, violating_ranges, violation_start FROM system.replication_constraint_stats WHERE violating_ranges > 0 ORDER BY violating_ranges DESC\""]}},{"id":"cockroach.replication_stats","title":"Show under-replicated / unavailable range counts","summary":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","description":"Show cluster-wide range health — total, under-replicated, unavailable, and over-replicated range counts, summed from system.replication_stats. Any non-zero unavailable count means data is offline; under-replicated means recovery is in progress.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on system.replication_stats.","Read-only."],"args":[],"examples":[{"title":"Range health summary","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT coalesce(sum(total_ranges),0) AS total, coalesce(sum(under_replicated_ranges),0) AS under_replicated, coalesce(sum(unavailable_ranges),0) AS unavailable, coalesce(sum(over_replicated_ranges),0) AS over_replicated FROM system.replication_stats\""]}},{"id":"cockroach.resume_job","title":"Resume a paused job (RESUME JOB)","summary":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","description":"Resume one paused job by id (from jobs). Use to continue a job paused with pause_job.","kind":"exec","risk":"medium","side_effects":["The target job resumes running."],"args":[{"name":"job_id","type":"integer","required":true,"description":"job_id from cockroach.jobs.","validation":{"min":1}}],"examples":[{"title":"Resume a job","args":{"job_id":891234567890123500}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"RESUME JOB {{ args.job_id }}\""]}},{"id":"cockroach.set_cluster_setting","title":"Set a cluster setting (SET CLUSTER SETTING)","summary":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","description":"Change one CockroachDB cluster setting cluster-wide — SET CLUSTER SETTING <name> = <value>. An unrestricted config write (rate limits, GC TTLs, feature flags) that can materially change cluster behavior, so risk:critical → default-denied. An operator allows it by explicit policy, and WHICH settings/values are permitted is a portal policy decision, not a hardcoded list. Read cockroach.cluster_settings first to see the current value.","kind":"exec","risk":"critical","side_effects":["The named cluster setting is changed for the WHOLE cluster, immediately.","Rate-limit / GC / admission settings can throttle or destabilize the cluster.","Reversible with another set (or \"= DEFAULT\")."],"args":[{"name":"name","type":"string","required":true,"description":"Cluster setting name, e.g. kv.snapshot_rebalance.max_rate (see cockroach.cluster_settings).","validation":{"pattern":"^[a-z][a-z0-9._]{0,127}$","max_length":128}},{"name":"value","type":"string","required":true,"description":"The value in CockroachDB literal form — a bare number/boolean (100, true, DEFAULT) or a quoted string ('64 MiB', '24h'). Passed verbatim into the statement; bounded so it can't break out of its slot.","validation":{"pattern":"^('[A-Za-z0-9 ._:+/-]{1,254}'|[A-Za-z0-9._+-]{1,64})$","max_length":256}}],"examples":[{"title":"Raise the snapshot rebalance rate","args":{"name":"kv.snapshot_rebalance.max_rate","value":"'64 MiB'"}},{"title":"Reset a setting to its default","args":{"name":"kv.range_split.by_load_enabled","value":"DEFAULT"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SET CLUSTER SETTING {{ args.name }} = {{ args.value }}\""]}},{"id":"cockroach.statement_stats","title":"Show top statement fingerprints by exec count","summary":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","description":"Show the busiest statement fingerprints — application, execution count, mean service latency, and the query text — from crdb_internal.statement_statistics (the data behind the DB Console's Statements page). Use to find the highest-volume or slowest statements.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.statement_statistics.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"Max fingerprints to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Busiest statements","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT app_name, (statistics->'statistics'->>'cnt')::INT AS count, (statistics->'statistics'->'svcLat'->>'mean')::FLOAT AS mean_svc_lat_s, left(metadata->>'query',200) AS query FROM crdb_internal.statement_statistics ORDER BY (statistics->'statistics'->>'cnt')::INT DESC LIMIT {{ args.limit }}\""]}},{"id":"cockroach.store_status","title":"Show per-store disk capacity / range counts","summary":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","description":"Show each store's capacity, available and used bytes, range and lease counts, and writes/sec from crdb_internal.kv_store_status. Use to spot a node running low on disk or carrying too many ranges.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.kv_store_status.","Read-only."],"args":[],"examples":[{"title":"Store capacity","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT node_id, store_id, capacity, available, used, logical_bytes, range_count, lease_count, writes_per_second FROM crdb_internal.kv_store_status ORDER BY node_id, store_id\""]}},{"id":"cockroach.table_ranges","title":"Show range count + size for one table","summary":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","description":"Show the ranges backing one table — range id, leaseholder, size in MB, and replica nodes — via SHOW RANGES ... WITH DETAILS. Use to find a table's data size and how its ranges are spread across nodes.","kind":"exec","risk":"low","side_effects":["One read-only SHOW RANGES query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}}],"examples":[{"title":"Ranges of movr.rides","args":{"database":"movr","table":"rides"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT range_id, lease_holder, range_size_mb, replicas FROM [SHOW RANGES FROM TABLE {{ args.database }}.{{ args.table }} WITH DETAILS]\""]}},{"id":"cockroach.table_row_counts","title":"Show estimated row counts per table","summary":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","description":"Show estimated row counts for every table from crdb_internal.table_row_statistics, largest first. Cheap (uses table statistics, not a COUNT). Use to find the biggest tables.","kind":"exec","risk":"low","side_effects":["One read-only SELECT on crdb_internal.table_row_statistics.","Read-only."],"args":[],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cockroach sql --url \"$COCKROACH_URL\" --format=tsv -e \"SELECT table_id, table_name, estimated_row_count FROM crdb_internal.table_row_statistics ORDER BY estimated_row_count DESC LIMIT 200\""]}}]}]},{"id":"consul","name":"HashiCorp Consul operations","version":"0.2.32","description":"Deep Consul ops — agent self/metrics/host introspection, operator raft + autopilot + reload, catalog (services + nodes + datacenters), health (passing/warning/critical) with force-pass/fail/warn check mutators, KV (get/list/recursive), ACL tokens/policies/roles, Connect mesh (CA roots, intentions), sessions, prepared queries, snapshots (save/inspect/restore), and narrow operator actions (deregister, maintenance, raft remove-peer). Auth via CONSUL_HTTP_ADDR + CONSUL_HTTP_TOKEN env vars.","vendor":"emisar","homepage":"https://emisar.dev/packs/consul","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/consul","content_hash":"sha256:a935ff58c5898f66172a4c1e1d4015e53303ba605de75ecc1bfdac761ea70879","tarball_url":"https://registry.emisar.dev/v1/packs/consul/0.2.32/a935ff58c5898f66172a4c1e1d4015e53303ba605de75ecc1bfdac761ea70879/pack.tar.gz","requires":{"os":["linux"],"binaries":["consul","curl","jq"]},"detect":{"binaries":[],"processes":["consul"],"ports":[8500]},"setup":{"summary":"Both the consul CLI and the curl-based API actions read the agent address, ACL token, and TLS certificate settings from the standard Consul environment variables on the runner host.","env":[{"name":"CONSUL_HTTP_ADDR","description":"Agent HTTP address, including scheme (the curl actions build URLs directly from it).","default":"http://127.0.0.1:8500","example":"http://consul.internal:8500"},{"name":"CONSUL_HTTP_TOKEN","description":"ACL token. Required when ACLs are enabled; its policy gates which actions succeed."},{"name":"CONSUL_CACERT","description":"Optional path to the CA certificate used to verify the agent's HTTPS certificate."},{"name":"CONSUL_CLIENT_CERT","description":"Optional path to the client certificate when the agent requires mutual TLS."},{"name":"CONSUL_CLIENT_KEY","description":"Optional path to the client certificate's private key when the agent requires mutual TLS."}],"notes":["Any Consul variable you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to `PATH` / `LANG` / `LC_ALL` / `TERM` by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","On a cluster with ACLs enabled the token must grant the rights the action needs — operator/write for raft_remove_peer and reload, service/node write for the maintenance and deregister mutators, and key/read for the KV reads.","For TLS-enabled agents use an `https://` `CONSUL_HTTP_ADDR`. `CONSUL_CACERT`, `CONSUL_CLIENT_CERT`, and `CONSUL_CLIENT_KEY` apply uniformly to the Consul CLI and raw API actions. Set the client certificate and key together."],"host_access":[{"actions":["consul.snapshot_save","consul.snapshot_inspect","consul.snapshot_restore"],"requirement":"Read and write Consul snapshot files in a dedicated host backup directory.","recipes":[{"name":"Create the Emisar Consul snapshot directory","commands":["sudo install -d -o root -g emisar -m 0770 /var/backups/emisar-consul"],"verify":["sudo -u emisar test -r /var/backups/emisar-consul","sudo -u emisar test -w /var/backups/emisar-consul"],"impact":"Every process running as emisar can read, replace, and delete snapshots in this directory. Consul snapshots contain raw KV, ACL, service, and session state."}]}],"verify":"consul.members"},"actions":[{"id":"consul.acl_token_self","title":"GET /v1/acl/token/self","summary":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","description":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","kind":"script","risk":"low","side_effects":["One ACL read request.","Read-only; the SecretID field returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[]},{"id":"consul.agent_checks","title":"GET /v1/agent/checks","summary":"List checks registered with the local agent + their current status.","description":"List checks registered with the local agent + their current status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local checks","args":{}}],"search_terms":[]},{"id":"consul.agent_host_info","title":"GET /v1/agent/host","summary":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","description":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[]},{"id":"consul.agent_metrics","title":"GET /v1/agent/metrics","summary":"Show current runtime metrics gauges + counters.","description":"Show current runtime metrics gauges + counters.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[]},{"id":"consul.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config, runtime, member, and ACL state.","description":"Show this agent's effective config, runtime, member, and ACL state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent self","args":{}}],"search_terms":[]},{"id":"consul.agent_services","title":"GET /v1/agent/services","summary":"List the services registered with the local agent.","description":"List the services registered with the local agent.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local services","args":{}}],"search_terms":[]},{"id":"consul.autopilot_state","title":"GET /v1/operator/autopilot/state","summary":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","description":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[]},{"id":"consul.catalog_datacenters","title":"GET /v1/catalog/datacenters","summary":"List all WAN-federated datacenters known to this server.","description":"List all WAN-federated datacenters known to this server.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Federated DCs","args":{}}],"search_terms":[]},{"id":"consul.catalog_service","title":"GET /v1/catalog/service/<name>","summary":"List all instances of one service across the cluster.","description":"List all instances of one service across the cluster.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Service instances","args":{"service":"api"}}],"search_terms":[]},{"id":"consul.connect_ca_configuration","title":"GET /v1/connect/ca/configuration","summary":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","description":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","kind":"script","risk":"medium","side_effects":["One API call.","Read-only; provider secret fields (Token, PrivateKey) are redacted before output."],"args":[],"examples":[{"title":"CA config","args":{}}],"search_terms":[]},{"id":"consul.connect_ca_roots","title":"GET /v1/connect/ca/roots","summary":"List currently-trusted root CAs for Connect mesh TLS.","description":"List currently-trusted root CAs for Connect mesh TLS.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"CA roots","args":{}}],"search_terms":[]},{"id":"consul.deregister_service","title":"consul services deregister","summary":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","description":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","kind":"exec","risk":"high","side_effects":["Service immediately disappears from discovery on this node.","Other nodes' registrations are unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID (not name).","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}}],"examples":[{"title":"Drop one","args":{"service_id":"api-1"}}],"search_terms":["stale service","ghost instance"],"command":{"binary":"consul","argv":["services","deregister","-id","{{ args.service_id }}"]}},{"id":"consul.destroy_session","title":"PUT /v1/session/destroy/<id>","summary":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","description":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","kind":"script","risk":"high","side_effects":["Session is destroyed immediately.","Held KV locks released (or keys deleted, if behavior=delete).","Distributed lock holders may need to handle the loss."],"args":[{"name":"session_id","type":"string","required":true,"description":"Session UUID.","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Destroy one","args":{"session_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["release stuck lock","force unlock"]},{"id":"consul.force_check_fail","title":"PUT /v1/agent/check/fail/<check_id>","summary":"Force one check into CRITICAL state. Service discovery stops returning it.","description":"Force one check into CRITICAL state. Service discovery stops returning it.","kind":"script","risk":"high","side_effects":["Targeted check transitions to CRITICAL.","Discovery routes traffic away from the associated service."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Drain one service instance","args":{"check_id":"service:api:1"}}],"search_terms":[]},{"id":"consul.force_check_pass","title":"PUT /v1/agent/check/pass/<check_id>","summary":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","description":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","kind":"script","risk":"high","side_effects":["Targeted check transitions to PASSING.","Services watching this check may resume routing traffic.","For non-TTL checks, the override is overwritten by the next actual run."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Force pass a TTL check","args":{"check_id":"service:api:1"}}],"search_terms":[]},{"id":"consul.force_check_warn","title":"PUT /v1/agent/check/warn/<check_id>","summary":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","description":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","kind":"script","risk":"high","side_effects":["Targeted check transitions to WARNING.","Strict service discovery (passing-only) routes away from it."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Mark warning","args":{"check_id":"service:api:1"}}],"search_terms":[]},{"id":"consul.intentions_list","title":"GET /v1/connect/intentions","summary":"List all Connect mesh intentions (allow/deny rules between services).","description":"List all Connect mesh intentions (allow/deny rules between services).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All intentions","args":{}}],"search_terms":[]},{"id":"consul.intentions_match","title":"GET /v1/connect/intentions/match (by destination)","summary":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","description":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"destination","type":"string","required":true,"description":"Destination service.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Match for api","args":{"destination":"api"}}],"search_terms":["what can talk to this service","connection denied"]},{"id":"consul.kv_get","title":"consul kv get <key>","summary":"Get the value at one KV key.","description":"Get the value at one KV key.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns the stored value, which may be a secret. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"key","type":"string","required":true,"description":"Full key path.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Value for config/api/log_level","args":{"key":"config/api/log_level"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","{{ args.key }}"]}},{"id":"consul.kv_get_recursive","title":"consul kv get -recurse <prefix>","summary":"Get all keys + values under a prefix.","description":"Get all keys + values under a prefix.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns every value under the prefix, which commonly includes secrets. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Recursive under config/","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-recurse","{{ args.prefix }}"]}},{"id":"consul.kv_list","title":"consul kv get -keys <prefix>","summary":"List all KV keys under one prefix.","description":"List all KV keys under one prefix.","kind":"exec","risk":"low","side_effects":["One KV request.","Read-only — keys only, no values."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"All keys under 'config/'","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-keys","{{ args.prefix }}"]}},{"id":"consul.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","description":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader address","args":{}}],"search_terms":["no leader","leader election"]},{"id":"consul.list_acl_policies","title":"consul acl policy list","summary":"List all ACL policies.","description":"List all ACL policies.","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL policies","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","policy","list"]}},{"id":"consul.list_acl_roles","title":"consul acl role list","summary":"List all ACL roles (groups of policies).","description":"List all ACL roles (groups of policies).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL roles","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","role","list"]}},{"id":"consul.list_acl_tokens","title":"consul acl token list","summary":"List ACL tokens (descriptions + accessor IDs only, not secrets).","description":"List ACL tokens (descriptions + accessor IDs only, not secrets).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL tokens","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","token","list"]}},{"id":"consul.list_checks_critical","title":"GET /v1/health/state/critical","summary":"List every check currently in CRITICAL state across the catalog.","description":"List every check currently in CRITICAL state across the catalog.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Critical checks","args":{}}],"search_terms":["what is failing","failing services"]},{"id":"consul.list_checks_warning","title":"GET /v1/health/state/warning","summary":"List every check currently in WARNING state.","description":"List every check currently in WARNING state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Warning checks","args":{}}],"search_terms":[]},{"id":"consul.list_nodes","title":"consul catalog nodes","summary":"List all registered nodes.","description":"List all registered nodes.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","nodes"]}},{"id":"consul.list_services","title":"consul catalog services","summary":"List all registered service names.","description":"List all registered service names.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Services","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","services"]}},{"id":"consul.list_sessions","title":"GET /v1/session/list","summary":"List active sessions cluster-wide: ID, node, TTL, behavior.","description":"List active sessions cluster-wide: ID, node, TTL, behavior.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":["who holds locks"]},{"id":"consul.members","title":"consul members","summary":"List all agents in the gossip pool with status, role, version.","description":"List all agents in the gossip pool with status, role, version.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["members"]}},{"id":"consul.node_health","title":"GET /v1/health/node/<node>","summary":"List all checks for one node + their status.","description":"List all checks for one node + their status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's checks","args":{"node":"node-1"}}],"search_terms":[]},{"id":"consul.node_maintenance","title":"consul maint -enable","summary":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","description":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","kind":"exec","risk":"high","side_effects":["All node service health checks report critical.","Service discovery routes traffic away from this node."],"args":[{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded in the health check.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain node","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-reason","{{ args.note }}"]}},{"id":"consul.node_services","title":"GET /v1/catalog/node-services/<node>","summary":"List all services registered against one node.","description":"List all services registered against one node.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's services","args":{"node":"node-1"}}],"search_terms":[]},{"id":"consul.prepared_queries_list","title":"GET /v1/query","summary":"List all defined prepared queries (named service-discovery templates with failover).","description":"List all defined prepared queries (named service-discovery templates with failover).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All prepared queries","args":{}}],"search_terms":[]},{"id":"consul.raft_peers","title":"consul operator raft list-peers","summary":"List the server peers with voter status, suffix, address.","description":"List the server peers with voter status, suffix, address.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":["lost quorum"],"command":{"binary":"consul","argv":["operator","raft","list-peers"]}},{"id":"consul.raft_remove_peer","title":"consul operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port, e.g. 10.0.0.5:8300).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:8300"}}],"search_terms":[],"command":{"binary":"consul","argv":["operator","raft","remove-peer","-address","{{ args.address }}"]}},{"id":"consul.registration_churn_snapshot","title":"Registration churn incident snapshot","summary":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","description":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","kind":"script","risk":"low","side_effects":["Five fixed read-only local-agent API calls separated by one bounded wait.","Service and check details omit check output, service metadata, and ACL tokens.","Never registers, deregisters, or changes a Consul object."],"args":[{"name":"sample_seconds","type":"integer","required":false,"default":12,"description":"Seconds between the two completed-interval metric samples.","validation":{"min":5,"max":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum services, failing checks, and loopback registrations returned per list.","validation":{"min":1,"max":200}}],"examples":[{"title":"Default incident snapshot","args":{}},{"title":"Short, tightly bounded sample","args":{"limit":25,"sample_seconds":5}}],"search_terms":["service registration churn","service deregistration storm","missing service discovery target","consul acl blocked registration","suspicious loopback registration","intermittent 502 bad gateway"]},{"id":"consul.reload","title":"consul reload","summary":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","description":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","kind":"exec","risk":"high","side_effects":["Local agent re-parses config.","Service + check + watch definitions reload.","Bind address, encryption keys, etc., remain at boot values."],"args":[],"examples":[{"title":"Reload local","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["reload"]}},{"id":"consul.service_health","title":"Health of a service's instances","summary":"Show per-node health for one service.","description":"Show per-node health for one service.","kind":"script","risk":"low","side_effects":["One health request.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Health for api","args":{"service":"api"}}],"search_terms":["service unhealthy"]},{"id":"consul.service_maintenance","title":"consul maint -enable -service <svc>","summary":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","description":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","kind":"exec","risk":"high","side_effects":["Service checks report critical.","Service discovery routes traffic away.","Other agents' services unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded by Consul.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain one service","args":{"service_id":"api-1"}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-service","{{ args.service_id }}","-reason","{{ args.note }}"]}},{"id":"consul.service_passing_only","title":"GET /v1/health/service/<name>?passing","summary":"List only healthy (all-passing) instances of one service. What service discovery would return.","description":"List only healthy (all-passing) instances of one service. What service discovery would return.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Healthy instances","args":{"service":"api"}}],"search_terms":[]},{"id":"consul.snapshot_inspect","title":"consul snapshot inspect <path>","summary":"Show a summary of one snapshot file — size, index, KV count, ACL count.","description":"Show a summary of one snapshot file — size, index, KV count, ACL count.","kind":"exec","risk":"low","side_effects":["Reads one snapshot file.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Inspect a backup","args":{"path":"/var/backups/emisar-consul/pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","inspect","{{ args.path }}"]}},{"id":"consul.snapshot_restore","title":"consul snapshot restore <path>","summary":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","description":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","kind":"exec","risk":"critical","side_effects":["All current Raft state is replaced.","KV, services, sessions, ACLs, intentions all swap to snapshot contents.","Brief outage during application.","Cannot be undone without another snapshot."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Restore from backup","args":{"path":"/var/backups/emisar-consul/pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","restore","{{ args.path }}"]}},{"id":"consul.snapshot_save","title":"consul snapshot save <path>","summary":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","description":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","kind":"exec","risk":"medium","side_effects":["One read of the entire state store.","File written at the configured path on the runner host.","Brief leader IO; no service impact."],"args":[{"name":"path","type":"string","required":true,"description":"Destination file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Pre-migration snap","args":{"path":"/var/backups/emisar-consul/pre-migration.snap"}}],"search_terms":["cluster backup"],"command":{"binary":"consul","argv":["snapshot","save","{{ args.path }}"]}}],"previous_versions":[{"version":"0.2.31","content_hash":"sha256:b01abab7aa671a70718e5d42b7aad1b32989bab8bebcf8aabb0e5d6c1a99818a","tarball_url":"https://registry.emisar.dev/v1/packs/consul/0.2.31/b01abab7aa671a70718e5d42b7aad1b32989bab8bebcf8aabb0e5d6c1a99818a/pack.tar.gz","actions":[{"id":"consul.acl_token_self","title":"GET /v1/acl/token/self","summary":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","description":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","kind":"script","risk":"low","side_effects":["One ACL read request.","Read-only; the SecretID field returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[]},{"id":"consul.agent_checks","title":"GET /v1/agent/checks","summary":"List checks registered with the local agent + their current status.","description":"List checks registered with the local agent + their current status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local checks","args":{}}],"search_terms":[]},{"id":"consul.agent_host_info","title":"GET /v1/agent/host","summary":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","description":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[]},{"id":"consul.agent_metrics","title":"GET /v1/agent/metrics","summary":"Show current runtime metrics gauges + counters.","description":"Show current runtime metrics gauges + counters.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[]},{"id":"consul.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config, runtime, member, and ACL state.","description":"Show this agent's effective config, runtime, member, and ACL state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent self","args":{}}],"search_terms":[]},{"id":"consul.agent_services","title":"GET /v1/agent/services","summary":"List the services registered with the local agent.","description":"List the services registered with the local agent.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local services","args":{}}],"search_terms":[]},{"id":"consul.autopilot_state","title":"GET /v1/operator/autopilot/state","summary":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","description":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[]},{"id":"consul.catalog_datacenters","title":"GET /v1/catalog/datacenters","summary":"List all WAN-federated datacenters known to this server.","description":"List all WAN-federated datacenters known to this server.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Federated DCs","args":{}}],"search_terms":[]},{"id":"consul.catalog_service","title":"GET /v1/catalog/service/<name>","summary":"List all instances of one service across the cluster.","description":"List all instances of one service across the cluster.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Service instances","args":{"service":"api"}}],"search_terms":[]},{"id":"consul.connect_ca_configuration","title":"GET /v1/connect/ca/configuration","summary":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","description":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","kind":"script","risk":"low","side_effects":["One API call.","Read-only; provider secret fields (Token, PrivateKey) are redacted before output."],"args":[],"examples":[{"title":"CA config","args":{}}],"search_terms":[]},{"id":"consul.connect_ca_roots","title":"GET /v1/connect/ca/roots","summary":"List currently-trusted root CAs for Connect mesh TLS.","description":"List currently-trusted root CAs for Connect mesh TLS.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"CA roots","args":{}}],"search_terms":[]},{"id":"consul.deregister_service","title":"consul services deregister","summary":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","description":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","kind":"exec","risk":"high","side_effects":["Service immediately disappears from discovery on this node.","Other nodes' registrations are unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID (not name).","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}}],"examples":[{"title":"Drop one","args":{"service_id":"api-1"}}],"search_terms":["stale service","ghost instance"],"command":{"binary":"consul","argv":["services","deregister","-id","{{ args.service_id }}"]}},{"id":"consul.destroy_session","title":"PUT /v1/session/destroy/<id>","summary":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","description":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","kind":"script","risk":"high","side_effects":["Session is destroyed immediately.","Held KV locks released (or keys deleted, if behavior=delete).","Distributed lock holders may need to handle the loss."],"args":[{"name":"session_id","type":"string","required":true,"description":"Session UUID.","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Destroy one","args":{"session_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["release stuck lock","force unlock"]},{"id":"consul.force_check_fail","title":"PUT /v1/agent/check/fail/<check_id>","summary":"Force one check into CRITICAL state. Service discovery stops returning it.","description":"Force one check into CRITICAL state. Service discovery stops returning it.","kind":"script","risk":"high","side_effects":["Targeted check transitions to CRITICAL.","Discovery routes traffic away from the associated service."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Drain one service instance","args":{"check_id":"service:api:1"}}],"search_terms":[]},{"id":"consul.force_check_pass","title":"PUT /v1/agent/check/pass/<check_id>","summary":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","description":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","kind":"script","risk":"high","side_effects":["Targeted check transitions to PASSING.","Services watching this check may resume routing traffic.","For non-TTL checks, the override is overwritten by the next actual run."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Force pass a TTL check","args":{"check_id":"service:api:1"}}],"search_terms":[]},{"id":"consul.force_check_warn","title":"PUT /v1/agent/check/warn/<check_id>","summary":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","description":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","kind":"script","risk":"high","side_effects":["Targeted check transitions to WARNING.","Strict service discovery (passing-only) routes away from it."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Mark warning","args":{"check_id":"service:api:1"}}],"search_terms":[]},{"id":"consul.intentions_list","title":"GET /v1/connect/intentions","summary":"List all Connect mesh intentions (allow/deny rules between services).","description":"List all Connect mesh intentions (allow/deny rules between services).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All intentions","args":{}}],"search_terms":[]},{"id":"consul.intentions_match","title":"GET /v1/connect/intentions/match (by destination)","summary":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","description":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"destination","type":"string","required":true,"description":"Destination service.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Match for api","args":{"destination":"api"}}],"search_terms":["what can talk to this service","connection denied"]},{"id":"consul.kv_get","title":"consul kv get <key>","summary":"Get the value at one KV key.","description":"Get the value at one KV key.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns the stored value, which may be a secret. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"key","type":"string","required":true,"description":"Full key path.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Value for config/api/log_level","args":{"key":"config/api/log_level"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","{{ args.key }}"]}},{"id":"consul.kv_get_recursive","title":"consul kv get -recurse <prefix>","summary":"Get all keys + values under a prefix.","description":"Get all keys + values under a prefix.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns every value under the prefix, which commonly includes secrets. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Recursive under config/","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-recurse","{{ args.prefix }}"]}},{"id":"consul.kv_list","title":"consul kv get -keys <prefix>","summary":"List all KV keys under one prefix.","description":"List all KV keys under one prefix.","kind":"exec","risk":"low","side_effects":["One KV request.","Read-only — keys only, no values."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"All keys under 'config/'","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-keys","{{ args.prefix }}"]}},{"id":"consul.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","description":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader address","args":{}}],"search_terms":["no leader","leader election"]},{"id":"consul.list_acl_policies","title":"consul acl policy list","summary":"List all ACL policies.","description":"List all ACL policies.","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL policies","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","policy","list"]}},{"id":"consul.list_acl_roles","title":"consul acl role list","summary":"List all ACL roles (groups of policies).","description":"List all ACL roles (groups of policies).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL roles","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","role","list"]}},{"id":"consul.list_acl_tokens","title":"consul acl token list","summary":"List ACL tokens (descriptions + accessor IDs only, not secrets).","description":"List ACL tokens (descriptions + accessor IDs only, not secrets).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL tokens","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","token","list"]}},{"id":"consul.list_checks_critical","title":"GET /v1/health/state/critical","summary":"List every check currently in CRITICAL state across the catalog.","description":"List every check currently in CRITICAL state across the catalog.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Critical checks","args":{}}],"search_terms":["what is failing","failing services"]},{"id":"consul.list_checks_warning","title":"GET /v1/health/state/warning","summary":"List every check currently in WARNING state.","description":"List every check currently in WARNING state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Warning checks","args":{}}],"search_terms":[]},{"id":"consul.list_nodes","title":"consul catalog nodes","summary":"List all registered nodes.","description":"List all registered nodes.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","nodes"]}},{"id":"consul.list_services","title":"consul catalog services","summary":"List all registered service names.","description":"List all registered service names.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Services","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","services"]}},{"id":"consul.list_sessions","title":"GET /v1/session/list","summary":"List active sessions cluster-wide: ID, node, TTL, behavior.","description":"List active sessions cluster-wide: ID, node, TTL, behavior.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":["who holds locks"]},{"id":"consul.members","title":"consul members","summary":"List all agents in the gossip pool with status, role, version.","description":"List all agents in the gossip pool with status, role, version.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["members"]}},{"id":"consul.node_health","title":"GET /v1/health/node/<node>","summary":"List all checks for one node + their status.","description":"List all checks for one node + their status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's checks","args":{"node":"node-1"}}],"search_terms":[]},{"id":"consul.node_maintenance","title":"consul maint -enable","summary":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","description":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","kind":"exec","risk":"high","side_effects":["All node service health checks report critical.","Service discovery routes traffic away from this node."],"args":[{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded in the health check.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain node","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-reason","{{ args.note }}"]}},{"id":"consul.node_services","title":"GET /v1/catalog/node-services/<node>","summary":"List all services registered against one node.","description":"List all services registered against one node.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's services","args":{"node":"node-1"}}],"search_terms":[]},{"id":"consul.prepared_queries_list","title":"GET /v1/query","summary":"List all defined prepared queries (named service-discovery templates with failover).","description":"List all defined prepared queries (named service-discovery templates with failover).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All prepared queries","args":{}}],"search_terms":[]},{"id":"consul.raft_peers","title":"consul operator raft list-peers","summary":"List the server peers with voter status, suffix, address.","description":"List the server peers with voter status, suffix, address.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":["lost quorum"],"command":{"binary":"consul","argv":["operator","raft","list-peers"]}},{"id":"consul.raft_remove_peer","title":"consul operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port, e.g. 10.0.0.5:8300).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:8300"}}],"search_terms":[],"command":{"binary":"consul","argv":["operator","raft","remove-peer","-address","{{ args.address }}"]}},{"id":"consul.registration_churn_snapshot","title":"Registration churn incident snapshot","summary":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","description":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","kind":"script","risk":"low","side_effects":["Five fixed read-only local-agent API calls separated by one bounded wait.","Service and check details omit check output, service metadata, and ACL tokens.","Never registers, deregisters, or changes a Consul object."],"args":[{"name":"sample_seconds","type":"integer","required":false,"default":12,"description":"Seconds between the two completed-interval metric samples.","validation":{"min":5,"max":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum services, failing checks, and loopback registrations returned per list.","validation":{"min":1,"max":200}}],"examples":[{"title":"Default incident snapshot","args":{}},{"title":"Short, tightly bounded sample","args":{"limit":25,"sample_seconds":5}}],"search_terms":["service registration churn","service deregistration storm","missing service discovery target","consul acl blocked registration","suspicious loopback registration","intermittent 502 bad gateway"]},{"id":"consul.reload","title":"consul reload","summary":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","description":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","kind":"exec","risk":"high","side_effects":["Local agent re-parses config.","Service + check + watch definitions reload.","Bind address, encryption keys, etc., remain at boot values."],"args":[],"examples":[{"title":"Reload local","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["reload"]}},{"id":"consul.service_health","title":"Health of a service's instances","summary":"Show per-node health for one service.","description":"Show per-node health for one service.","kind":"script","risk":"low","side_effects":["One health request.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Health for api","args":{"service":"api"}}],"search_terms":["service unhealthy"]},{"id":"consul.service_maintenance","title":"consul maint -enable -service <svc>","summary":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","description":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","kind":"exec","risk":"high","side_effects":["Service checks report critical.","Service discovery routes traffic away.","Other agents' services unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded by Consul.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain one service","args":{"service_id":"api-1"}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-service","{{ args.service_id }}","-reason","{{ args.note }}"]}},{"id":"consul.service_passing_only","title":"GET /v1/health/service/<name>?passing","summary":"List only healthy (all-passing) instances of one service. What service discovery would return.","description":"List only healthy (all-passing) instances of one service. What service discovery would return.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Healthy instances","args":{"service":"api"}}],"search_terms":[]},{"id":"consul.snapshot_inspect","title":"consul snapshot inspect <path>","summary":"Show a summary of one snapshot file — size, index, KV count, ACL count.","description":"Show a summary of one snapshot file — size, index, KV count, ACL count.","kind":"exec","risk":"low","side_effects":["Reads one snapshot file.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Inspect a backup","args":{"path":"/var/backups/emisar-consul/pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","inspect","{{ args.path }}"]}},{"id":"consul.snapshot_restore","title":"consul snapshot restore <path>","summary":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","description":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","kind":"exec","risk":"critical","side_effects":["All current Raft state is replaced.","KV, services, sessions, ACLs, intentions all swap to snapshot contents.","Brief outage during application.","Cannot be undone without another snapshot."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Restore from backup","args":{"path":"/var/backups/emisar-consul/pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","restore","{{ args.path }}"]}},{"id":"consul.snapshot_save","title":"consul snapshot save <path>","summary":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","description":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","kind":"exec","risk":"medium","side_effects":["One read of the entire state store.","File written at the configured path on the runner host.","Brief leader IO; no service impact."],"args":[{"name":"path","type":"string","required":true,"description":"Destination file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Pre-migration snap","args":{"path":"/var/backups/emisar-consul/pre-migration.snap"}}],"search_terms":["cluster backup"],"command":{"binary":"consul","argv":["snapshot","save","{{ args.path }}"]}}]},{"version":"0.2.29","content_hash":"sha256:019cf4b68046c36a7037107e0096f9e2d155f1f233bdda0228d311ac8f65c806","tarball_url":"https://registry.emisar.dev/v1/packs/consul/0.2.29/019cf4b68046c36a7037107e0096f9e2d155f1f233bdda0228d311ac8f65c806/pack.tar.gz","actions":[{"id":"consul.acl_token_self","title":"GET /v1/acl/token/self","summary":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","description":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","kind":"exec","risk":"low","side_effects":["One ACL read request.","Read-only; the SecretID field returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/acl/token/self\""]}},{"id":"consul.agent_checks","title":"GET /v1/agent/checks","summary":"List checks registered with the local agent + their current status.","description":"List checks registered with the local agent + their current status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local checks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/checks\""]}},{"id":"consul.agent_host_info","title":"GET /v1/agent/host","summary":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","description":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/host\""]}},{"id":"consul.agent_metrics","title":"GET /v1/agent/metrics","summary":"Show current runtime metrics gauges + counters.","description":"Show current runtime metrics gauges + counters.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/metrics\""]}},{"id":"consul.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config, runtime, member, and ACL state.","description":"Show this agent's effective config, runtime, member, and ACL state.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent self","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/self\""]}},{"id":"consul.agent_services","title":"GET /v1/agent/services","summary":"List the services registered with the local agent.","description":"List the services registered with the local agent.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local services","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/services\""]}},{"id":"consul.autopilot_state","title":"GET /v1/operator/autopilot/state","summary":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","description":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/operator/autopilot/state\""]}},{"id":"consul.catalog_datacenters","title":"GET /v1/catalog/datacenters","summary":"List all WAN-federated datacenters known to this server.","description":"List all WAN-federated datacenters known to this server.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Federated DCs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/catalog/datacenters\""]}},{"id":"consul.catalog_service","title":"GET /v1/catalog/service/<name>","summary":"List all instances of one service across the cluster.","description":"List all instances of one service across the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Service instances","args":{"service":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/catalog/service/${1}\"","emisar","{{ args.service }}"]}},{"id":"consul.connect_ca_configuration","title":"GET /v1/connect/ca/configuration","summary":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","description":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only; provider secret fields (Token, PrivateKey) are redacted before output."],"args":[],"examples":[{"title":"CA config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/ca/configuration\""]}},{"id":"consul.connect_ca_roots","title":"GET /v1/connect/ca/roots","summary":"List currently-trusted root CAs for Connect mesh TLS.","description":"List currently-trusted root CAs for Connect mesh TLS.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"CA roots","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/ca/roots\""]}},{"id":"consul.deregister_service","title":"consul services deregister","summary":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","description":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","kind":"exec","risk":"high","side_effects":["Service immediately disappears from discovery on this node.","Other nodes' registrations are unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID (not name).","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}}],"examples":[{"title":"Drop one","args":{"service_id":"api-1"}}],"search_terms":["stale service","ghost instance"],"command":{"binary":"consul","argv":["services","deregister","-id","{{ args.service_id }}"]}},{"id":"consul.destroy_session","title":"PUT /v1/session/destroy/<id>","summary":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","description":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","kind":"exec","risk":"high","side_effects":["Session is destroyed immediately.","Held KV locks released (or keys deleted, if behavior=delete).","Distributed lock holders may need to handle the loss."],"args":[{"name":"session_id","type":"string","required":true,"description":"Session UUID.","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Destroy one","args":{"session_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["release stuck lock","force unlock"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/session/destroy/${1}\"","emisar","{{ args.session_id }}"]}},{"id":"consul.force_check_fail","title":"PUT /v1/agent/check/fail/<check_id>","summary":"Force one check into CRITICAL state. Service discovery stops returning it.","description":"Force one check into CRITICAL state. Service discovery stops returning it.","kind":"exec","risk":"high","side_effects":["Targeted check transitions to CRITICAL.","Discovery routes traffic away from the associated service."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Drain one service instance","args":{"check_id":"service:api:1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf \"X-Consul-Token: %s\\n\" \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- --data-urlencode \"note=$NOTE\" -G \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/check/fail/$CHECK_ID\""]}},{"id":"consul.force_check_pass","title":"PUT /v1/agent/check/pass/<check_id>","summary":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","description":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","kind":"exec","risk":"high","side_effects":["Targeted check transitions to PASSING.","Services watching this check may resume routing traffic.","For non-TTL checks, the override is overwritten by the next actual run."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Force pass a TTL check","args":{"check_id":"service:api:1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf \"X-Consul-Token: %s\\n\" \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- --data-urlencode \"note=$NOTE\" -G \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/check/pass/$CHECK_ID\""]}},{"id":"consul.force_check_warn","title":"PUT /v1/agent/check/warn/<check_id>","summary":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","description":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","kind":"exec","risk":"high","side_effects":["Targeted check transitions to WARNING.","Strict service discovery (passing-only) routes away from it."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Mark warning","args":{"check_id":"service:api:1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf \"X-Consul-Token: %s\\n\" \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- --data-urlencode \"note=$NOTE\" -G \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/check/warn/$CHECK_ID\""]}},{"id":"consul.intentions_list","title":"GET /v1/connect/intentions","summary":"List all Connect mesh intentions (allow/deny rules between services).","description":"List all Connect mesh intentions (allow/deny rules between services).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All intentions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/intentions\""]}},{"id":"consul.intentions_match","title":"GET /v1/connect/intentions/match (by destination)","summary":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","description":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"destination","type":"string","required":true,"description":"Destination service.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Match for api","args":{"destination":"api"}}],"search_terms":["what can talk to this service","connection denied"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/intentions/match?by=destination&name=${1}\"","emisar","{{ args.destination }}"]}},{"id":"consul.kv_get","title":"consul kv get <key>","summary":"Get the value at one KV key.","description":"Get the value at one KV key.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns the stored value, which may be a secret. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"key","type":"string","required":true,"description":"Full key path.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Value for config/api/log_level","args":{"key":"config/api/log_level"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","{{ args.key }}"]}},{"id":"consul.kv_get_recursive","title":"consul kv get -recurse <prefix>","summary":"Get all keys + values under a prefix.","description":"Get all keys + values under a prefix.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns every value under the prefix, which commonly includes secrets. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Recursive under config/","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-recurse","{{ args.prefix }}"]}},{"id":"consul.kv_list","title":"consul kv get -keys <prefix>","summary":"List all KV keys under one prefix.","description":"List all KV keys under one prefix.","kind":"exec","risk":"low","side_effects":["One KV request.","Read-only — keys only, no values."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"All keys under 'config/'","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-keys","{{ args.prefix }}"]}},{"id":"consul.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","description":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader address","args":{}}],"search_terms":["no leader","leader election"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/status/leader\""]}},{"id":"consul.list_acl_policies","title":"consul acl policy list","summary":"List all ACL policies.","description":"List all ACL policies.","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL policies","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","policy","list"]}},{"id":"consul.list_acl_roles","title":"consul acl role list","summary":"List all ACL roles (groups of policies).","description":"List all ACL roles (groups of policies).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL roles","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","role","list"]}},{"id":"consul.list_acl_tokens","title":"consul acl token list","summary":"List ACL tokens (descriptions + accessor IDs only, not secrets).","description":"List ACL tokens (descriptions + accessor IDs only, not secrets).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL tokens","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","token","list"]}},{"id":"consul.list_checks_critical","title":"GET /v1/health/state/critical","summary":"List every check currently in CRITICAL state across the catalog.","description":"List every check currently in CRITICAL state across the catalog.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Critical checks","args":{}}],"search_terms":["what is failing","failing services"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/state/critical\""]}},{"id":"consul.list_checks_warning","title":"GET /v1/health/state/warning","summary":"List every check currently in WARNING state.","description":"List every check currently in WARNING state.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Warning checks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/state/warning\""]}},{"id":"consul.list_nodes","title":"consul catalog nodes","summary":"List all registered nodes.","description":"List all registered nodes.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","nodes"]}},{"id":"consul.list_services","title":"consul catalog services","summary":"List all registered service names.","description":"List all registered service names.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Services","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","services"]}},{"id":"consul.list_sessions","title":"GET /v1/session/list","summary":"List active sessions cluster-wide: ID, node, TTL, behavior.","description":"List active sessions cluster-wide: ID, node, TTL, behavior.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":["who holds locks"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/session/list\""]}},{"id":"consul.members","title":"consul members","summary":"List all agents in the gossip pool with status, role, version.","description":"List all agents in the gossip pool with status, role, version.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["members"]}},{"id":"consul.node_health","title":"GET /v1/health/node/<node>","summary":"List all checks for one node + their status.","description":"List all checks for one node + their status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's checks","args":{"node":"node-1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/node/${1}\"","emisar","{{ args.node }}"]}},{"id":"consul.node_maintenance","title":"consul maint -enable","summary":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","description":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","kind":"exec","risk":"high","side_effects":["All node service health checks report critical.","Service discovery routes traffic away from this node."],"args":[{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded in the health check.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain node","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-reason","{{ args.note }}"]}},{"id":"consul.node_services","title":"GET /v1/catalog/node-services/<node>","summary":"List all services registered against one node.","description":"List all services registered against one node.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's services","args":{"node":"node-1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/catalog/node-services/${1}\"","emisar","{{ args.node }}"]}},{"id":"consul.prepared_queries_list","title":"GET /v1/query","summary":"List all defined prepared queries (named service-discovery templates with failover).","description":"List all defined prepared queries (named service-discovery templates with failover).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All prepared queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/query\""]}},{"id":"consul.raft_peers","title":"consul operator raft list-peers","summary":"List the server peers with voter status, suffix, address.","description":"List the server peers with voter status, suffix, address.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":["lost quorum"],"command":{"binary":"consul","argv":["operator","raft","list-peers"]}},{"id":"consul.raft_remove_peer","title":"consul operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port, e.g. 10.0.0.5:8300).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:8300"}}],"search_terms":[],"command":{"binary":"consul","argv":["operator","raft","remove-peer","-address","{{ args.address }}"]}},{"id":"consul.registration_churn_snapshot","title":"Registration churn incident snapshot","summary":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","description":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","kind":"script","risk":"low","side_effects":["Five fixed read-only local-agent API calls separated by one bounded wait.","Service and check details omit check output, service metadata, and ACL tokens.","Never registers, deregisters, or changes a Consul object."],"args":[{"name":"sample_seconds","type":"integer","required":false,"default":12,"description":"Seconds between the two completed-interval metric samples.","validation":{"min":5,"max":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum services, failing checks, and loopback registrations returned per list.","validation":{"min":1,"max":200}}],"examples":[{"title":"Default incident snapshot","args":{}},{"title":"Short, tightly bounded sample","args":{"limit":25,"sample_seconds":5}}],"search_terms":["service registration churn","service deregistration storm","missing service discovery target","consul acl blocked registration","suspicious loopback registration","intermittent 502 bad gateway"]},{"id":"consul.reload","title":"consul reload","summary":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","description":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","kind":"exec","risk":"high","side_effects":["Local agent re-parses config.","Service + check + watch definitions reload.","Bind address, encryption keys, etc., remain at boot values."],"args":[],"examples":[{"title":"Reload local","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["reload"]}},{"id":"consul.service_health","title":"Health of a service's instances","summary":"Show per-node health for one service.","description":"Show per-node health for one service.","kind":"exec","risk":"low","side_effects":["One health request.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Health for api","args":{"service":"api"}}],"search_terms":["service unhealthy"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/service/${1}\" -H @-","emisar","{{ args.service }}"]}},{"id":"consul.service_maintenance","title":"consul maint -enable -service <svc>","summary":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","description":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","kind":"exec","risk":"high","side_effects":["Service checks report critical.","Service discovery routes traffic away.","Other agents' services unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded by Consul.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain one service","args":{"service_id":"api-1"}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-service","{{ args.service_id }}","-reason","{{ args.note }}"]}},{"id":"consul.service_passing_only","title":"GET /v1/health/service/<name>?passing","summary":"List only healthy (all-passing) instances of one service. What service discovery would return.","description":"List only healthy (all-passing) instances of one service. What service discovery would return.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Healthy instances","args":{"service":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/service/${1}?passing\"","emisar","{{ args.service }}"]}},{"id":"consul.snapshot_inspect","title":"consul snapshot inspect <path>","summary":"Show a summary of one snapshot file — size, index, KV count, ACL count.","description":"Show a summary of one snapshot file — size, index, KV count, ACL count.","kind":"exec","risk":"low","side_effects":["Reads one snapshot file.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Inspect a backup","args":{"path":"/var/backups/consul-pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","inspect","{{ args.path }}"]}},{"id":"consul.snapshot_restore","title":"consul snapshot restore <path>","summary":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","description":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","kind":"exec","risk":"critical","side_effects":["All current Raft state is replaced.","KV, services, sessions, ACLs, intentions all swap to snapshot contents.","Brief outage during application.","Cannot be undone without another snapshot."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Restore from backup","args":{"path":"/var/backups/consul-pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","restore","{{ args.path }}"]}},{"id":"consul.snapshot_save","title":"consul snapshot save <path>","summary":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","description":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","kind":"exec","risk":"medium","side_effects":["One read of the entire state store.","File written at the configured path on the runner host.","Brief leader IO; no service impact."],"args":[{"name":"path","type":"string","required":true,"description":"Destination file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Pre-migration snap","args":{"path":"/var/backups/consul-pre-migration.snap"}}],"search_terms":["cluster backup"],"command":{"binary":"consul","argv":["snapshot","save","{{ args.path }}"]}}]},{"version":"0.2.27","content_hash":"sha256:b4c3a9cd3196268bda24a2a6457a0fc68006db9792fa687dd1982711ad03938a","tarball_url":"https://registry.emisar.dev/v1/packs/consul/0.2.27/b4c3a9cd3196268bda24a2a6457a0fc68006db9792fa687dd1982711ad03938a/pack.tar.gz","actions":[{"id":"consul.acl_token_self","title":"GET /v1/acl/token/self","summary":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","description":"Show metadata on the runner's own token — accessor, policies, roles, expiration. The SecretID the API returns is redacted from the output.","kind":"exec","risk":"low","side_effects":["One ACL read request.","Read-only; the SecretID field returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/acl/token/self\""]}},{"id":"consul.agent_checks","title":"GET /v1/agent/checks","summary":"List checks registered with the local agent + their current status.","description":"List checks registered with the local agent + their current status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local checks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/checks\""]}},{"id":"consul.agent_host_info","title":"GET /v1/agent/host","summary":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","description":"Show host info: OS, CPU, memory, filesystem, network from the agent's view.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/host\""]}},{"id":"consul.agent_metrics","title":"GET /v1/agent/metrics","summary":"Show current runtime metrics gauges + counters.","description":"Show current runtime metrics gauges + counters.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Metrics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/metrics\""]}},{"id":"consul.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config, runtime, member, and ACL state.","description":"Show this agent's effective config, runtime, member, and ACL state.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent self","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/self\""]}},{"id":"consul.agent_services","title":"GET /v1/agent/services","summary":"List the services registered with the local agent.","description":"List the services registered with the local agent.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Local services","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/services\""]}},{"id":"consul.autopilot_state","title":"GET /v1/operator/autopilot/state","summary":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","description":"Show the Autopilot view of cluster health: server stabilization, leader, failure tolerance.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/operator/autopilot/state\""]}},{"id":"consul.catalog_datacenters","title":"GET /v1/catalog/datacenters","summary":"List all WAN-federated datacenters known to this server.","description":"List all WAN-federated datacenters known to this server.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Federated DCs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/catalog/datacenters\""]}},{"id":"consul.catalog_service","title":"GET /v1/catalog/service/<name>","summary":"List all instances of one service across the cluster.","description":"List all instances of one service across the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Service instances","args":{"service":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/catalog/service/${1}\"","emisar","{{ args.service }}"]}},{"id":"consul.connect_ca_configuration","title":"GET /v1/connect/ca/configuration","summary":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","description":"Show CA provider configuration (which CA, intermediate cert TTL, etc). Provider secrets the config map may carry — the Vault provider's Token and the built-in provider's PrivateKey — are redacted from the output.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only; provider secret fields (Token, PrivateKey) are redacted before output."],"args":[],"examples":[{"title":"CA config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/ca/configuration\""]}},{"id":"consul.connect_ca_roots","title":"GET /v1/connect/ca/roots","summary":"List currently-trusted root CAs for Connect mesh TLS.","description":"List currently-trusted root CAs for Connect mesh TLS.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"CA roots","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/ca/roots\""]}},{"id":"consul.deregister_service","title":"consul services deregister","summary":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","description":"Remove one service registration from this agent; it disappears from discovery immediately and clients stop being routed to that instance.","kind":"exec","risk":"high","side_effects":["Service immediately disappears from discovery on this node.","Other nodes' registrations are unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID (not name).","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}}],"examples":[{"title":"Drop one","args":{"service_id":"api-1"}}],"search_terms":["stale service","ghost instance"],"command":{"binary":"consul","argv":["services","deregister","-id","{{ args.service_id }}"]}},{"id":"consul.destroy_session","title":"PUT /v1/session/destroy/<id>","summary":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","description":"Destroy one session. Any locks held are released; KV entries with release behavior are unlocked.","kind":"exec","risk":"high","side_effects":["Session is destroyed immediately.","Held KV locks released (or keys deleted, if behavior=delete).","Distributed lock holders may need to handle the loss."],"args":[{"name":"session_id","type":"string","required":true,"description":"Session UUID.","validation":{"pattern":"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"}}],"examples":[{"title":"Destroy one","args":{"session_id":"abc12345-1234-5678-9abc-def012345678"}}],"search_terms":["release stuck lock","force unlock"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/session/destroy/${1}\"","emisar","{{ args.session_id }}"]}},{"id":"consul.force_check_fail","title":"PUT /v1/agent/check/fail/<check_id>","summary":"Force one check into CRITICAL state. Service discovery stops returning it.","description":"Force one check into CRITICAL state. Service discovery stops returning it.","kind":"exec","risk":"high","side_effects":["Targeted check transitions to CRITICAL.","Discovery routes traffic away from the associated service."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Drain one service instance","args":{"check_id":"service:api:1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf \"X-Consul-Token: %s\\n\" \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- --data-urlencode \"note=$NOTE\" -G \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/check/fail/$CHECK_ID\""]}},{"id":"consul.force_check_pass","title":"PUT /v1/agent/check/pass/<check_id>","summary":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","description":"Force one TTL check into the PASSING state; discovery resumes routing traffic to the service even if it is genuinely unhealthy. The check stays passing until the next TTL expires.","kind":"exec","risk":"high","side_effects":["Targeted check transitions to PASSING.","Services watching this check may resume routing traffic.","For non-TTL checks, the override is overwritten by the next actual run."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached to the check.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Force pass a TTL check","args":{"check_id":"service:api:1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf \"X-Consul-Token: %s\\n\" \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- --data-urlencode \"note=$NOTE\" -G \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/check/pass/$CHECK_ID\""]}},{"id":"consul.force_check_warn","title":"PUT /v1/agent/check/warn/<check_id>","summary":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","description":"Force one check into WARNING state; strict (passing-only) discovery stops returning the associated service.","kind":"exec","risk":"high","side_effects":["Targeted check transitions to WARNING.","Strict service discovery (passing-only) routes away from it."],"args":[{"name":"check_id","type":"string","required":true,"description":"Check ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.:\\-]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator override","description":"Note attached.","validation":{"pattern":"^[A-Za-z0-9 _.,:/()#@=+-]{1,255}$"}}],"examples":[{"title":"Mark warning","args":{"check_id":"service:api:1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf \"X-Consul-Token: %s\\n\" \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -XPUT -H @- --data-urlencode \"note=$NOTE\" -G \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/agent/check/warn/$CHECK_ID\""]}},{"id":"consul.intentions_list","title":"GET /v1/connect/intentions","summary":"List all Connect mesh intentions (allow/deny rules between services).","description":"List all Connect mesh intentions (allow/deny rules between services).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All intentions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/intentions\""]}},{"id":"consul.intentions_match","title":"GET /v1/connect/intentions/match (by destination)","summary":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","description":"List all intentions whose destination is the named service. Use to answer \"what can talk to X?\".","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"destination","type":"string","required":true,"description":"Destination service.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Match for api","args":{"destination":"api"}}],"search_terms":["what can talk to this service","connection denied"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/connect/intentions/match?by=destination&name=${1}\"","emisar","{{ args.destination }}"]}},{"id":"consul.kv_get","title":"consul kv get <key>","summary":"Get the value at one KV key.","description":"Get the value at one KV key.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns the stored value, which may be a secret. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"key","type":"string","required":true,"description":"Full key path.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Value for config/api/log_level","args":{"key":"config/api/log_level"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","{{ args.key }}"]}},{"id":"consul.kv_get_recursive","title":"consul kv get -recurse <prefix>","summary":"Get all keys + values under a prefix.","description":"Get all keys + values under a prefix.","kind":"exec","risk":"high","side_effects":["One KV request.","Read-only, but returns every value under the prefix, which commonly includes secrets. Approval-gated for that reason; redaction is a pattern-bound backstop, not a guarantee."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Recursive under config/","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-recurse","{{ args.prefix }}"]}},{"id":"consul.kv_list","title":"consul kv get -keys <prefix>","summary":"List all KV keys under one prefix.","description":"List all KV keys under one prefix.","kind":"exec","risk":"low","side_effects":["One KV request.","Read-only — keys only, no values."],"args":[{"name":"prefix","type":"string","required":true,"description":"Key prefix.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"All keys under 'config/'","args":{"prefix":"config/"}}],"search_terms":[],"command":{"binary":"consul","argv":["kv","get","-keys","{{ args.prefix }}"]}},{"id":"consul.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","description":"Show the current Raft leader address for this datacenter. Reads the status endpoint, which is not ACL-gated, so it answers \"is there a leader?\" even when no CONSUL_HTTP_TOKEN is set.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader address","args":{}}],"search_terms":["no leader","leader election"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/status/leader\""]}},{"id":"consul.list_acl_policies","title":"consul acl policy list","summary":"List all ACL policies.","description":"List all ACL policies.","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL policies","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","policy","list"]}},{"id":"consul.list_acl_roles","title":"consul acl role list","summary":"List all ACL roles (groups of policies).","description":"List all ACL roles (groups of policies).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL roles","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","role","list"]}},{"id":"consul.list_acl_tokens","title":"consul acl token list","summary":"List ACL tokens (descriptions + accessor IDs only, not secrets).","description":"List ACL tokens (descriptions + accessor IDs only, not secrets).","kind":"exec","risk":"low","side_effects":["One ACL request.","Read-only."],"args":[],"examples":[{"title":"ACL tokens","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["acl","token","list"]}},{"id":"consul.list_checks_critical","title":"GET /v1/health/state/critical","summary":"List every check currently in CRITICAL state across the catalog.","description":"List every check currently in CRITICAL state across the catalog.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Critical checks","args":{}}],"search_terms":["what is failing","failing services"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/state/critical\""]}},{"id":"consul.list_checks_warning","title":"GET /v1/health/state/warning","summary":"List every check currently in WARNING state.","description":"List every check currently in WARNING state.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Warning checks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/state/warning\""]}},{"id":"consul.list_nodes","title":"consul catalog nodes","summary":"List all registered nodes.","description":"List all registered nodes.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","nodes"]}},{"id":"consul.list_services","title":"consul catalog services","summary":"List all registered service names.","description":"List all registered service names.","kind":"exec","risk":"low","side_effects":["One catalog request.","Read-only."],"args":[],"examples":[{"title":"Services","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["catalog","services"]}},{"id":"consul.list_sessions","title":"GET /v1/session/list","summary":"List active sessions cluster-wide: ID, node, TTL, behavior.","description":"List active sessions cluster-wide: ID, node, TTL, behavior.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":["who holds locks"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/session/list\""]}},{"id":"consul.members","title":"consul members","summary":"List all agents in the gossip pool with status, role, version.","description":"List all agents in the gossip pool with status, role, version.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["members"]}},{"id":"consul.node_health","title":"GET /v1/health/node/<node>","summary":"List all checks for one node + their status.","description":"List all checks for one node + their status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's checks","args":{"node":"node-1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/node/${1}\"","emisar","{{ args.node }}"]}},{"id":"consul.node_maintenance","title":"consul maint -enable","summary":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","description":"Enable maintenance mode on this agent's node. Health checks fail until disabled.","kind":"exec","risk":"high","side_effects":["All node service health checks report critical.","Service discovery routes traffic away from this node."],"args":[{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded in the health check.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain node","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-reason","{{ args.note }}"]}},{"id":"consul.node_services","title":"GET /v1/catalog/node-services/<node>","summary":"List all services registered against one node.","description":"List all services registered against one node.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One node's services","args":{"node":"node-1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/catalog/node-services/${1}\"","emisar","{{ args.node }}"]}},{"id":"consul.prepared_queries_list","title":"GET /v1/query","summary":"List all defined prepared queries (named service-discovery templates with failover).","description":"List all defined prepared queries (named service-discovery templates with failover).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All prepared queries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/query\""]}},{"id":"consul.raft_peers","title":"consul operator raft list-peers","summary":"List the server peers with voter status, suffix, address.","description":"List the server peers with voter status, suffix, address.","kind":"exec","risk":"low","side_effects":["One agent call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":["lost quorum"],"command":{"binary":"consul","argv":["operator","raft","list-peers"]}},{"id":"consul.raft_remove_peer","title":"consul operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port, e.g. 10.0.0.5:8300).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:8300"}}],"search_terms":[],"command":{"binary":"consul","argv":["operator","raft","remove-peer","-address","{{ args.address }}"]}},{"id":"consul.registration_churn_snapshot","title":"Registration churn incident snapshot","summary":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","description":"Sample the local Consul agent's completed telemetry interval twice, then return a compact JSON incident snapshot with registration, deregistration, and ACL-blocked mutation deltas plus bounded local services, failing checks, and services explicitly registered to loopback. The metrics endpoint reports completed ten-second aggregation intervals, so this is a focused diagnostic sample rather than an audit log. Deltas are null when both reads observe the same completed interval.","kind":"script","risk":"low","side_effects":["Five fixed read-only local-agent API calls separated by one bounded wait.","Service and check details omit check output, service metadata, and ACL tokens.","Never registers, deregisters, or changes a Consul object."],"args":[{"name":"sample_seconds","type":"integer","required":false,"default":12,"description":"Seconds between the two completed-interval metric samples.","validation":{"min":5,"max":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum services, failing checks, and loopback registrations returned per list.","validation":{"min":1,"max":200}}],"examples":[{"title":"Default incident snapshot","args":{}},{"title":"Short, tightly bounded sample","args":{"limit":25,"sample_seconds":5}}],"search_terms":["service registration churn","service deregistration storm","missing service discovery target","consul acl blocked registration","suspicious loopback registration","intermittent 502 bad gateway"]},{"id":"consul.reload","title":"consul reload","summary":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","description":"Reload the local agent's config (re-reads HCL files). Some settings can't be reloaded — see consul docs.","kind":"exec","risk":"high","side_effects":["Local agent re-parses config.","Service + check + watch definitions reload.","Bind address, encryption keys, etc., remain at boot values."],"args":[],"examples":[{"title":"Reload local","args":{}}],"search_terms":[],"command":{"binary":"consul","argv":["reload"]}},{"id":"consul.service_health","title":"Health of a service's instances","summary":"Show per-node health for one service.","description":"Show per-node health for one service.","kind":"exec","risk":"low","side_effects":["One health request.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Health for api","args":{"service":"api"}}],"search_terms":["service unhealthy"],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/service/${1}\" -H @-","emisar","{{ args.service }}"]}},{"id":"consul.service_maintenance","title":"consul maint -enable -service <svc>","summary":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","description":"Put one local-agent service into maintenance mode. Its checks report critical until disabled.","kind":"exec","risk":"high","side_effects":["Service checks report critical.","Service discovery routes traffic away.","Other agents' services unaffected."],"args":[{"name":"service_id","type":"string","required":true,"description":"Service ID.","validation":{"pattern":"^[a-zA-Z0-9_.:][a-zA-Z0-9_.\\-:]{0,127}$"}},{"name":"note","type":"string","required":false,"default":"operator action","description":"Maintenance reason recorded by Consul.","validation":{"pattern":"^.{1,255}$"}}],"examples":[{"title":"Drain one service","args":{"service_id":"api-1"}}],"search_terms":[],"command":{"binary":"consul","argv":["maint","-enable","-service","{{ args.service_id }}","-reason","{{ args.note }}"]}},{"id":"consul.service_passing_only","title":"GET /v1/health/service/<name>?passing","summary":"List only healthy (all-passing) instances of one service. What service discovery would return.","description":"List only healthy (all-passing) instances of one service. What service discovery would return.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Healthy instances","args":{"service":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ [ -n \"$CONSUL_HTTP_TOKEN\" ] && printf 'X-Consul-Token: %s\\n' \"$CONSUL_HTTP_TOKEN\"; } | curl -fsS --globoff --proto =http,https -H @- \"${CONSUL_HTTP_ADDR:-http://127.0.0.1:8500}/v1/health/service/${1}?passing\"","emisar","{{ args.service }}"]}},{"id":"consul.snapshot_inspect","title":"consul snapshot inspect <path>","summary":"Show a summary of one snapshot file — size, index, KV count, ACL count.","description":"Show a summary of one snapshot file — size, index, KV count, ACL count.","kind":"exec","risk":"low","side_effects":["Reads one snapshot file.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Inspect a backup","args":{"path":"/var/backups/consul-pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","inspect","{{ args.path }}"]}},{"id":"consul.snapshot_restore","title":"consul snapshot restore <path>","summary":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","description":"Restore cluster state from a snapshot. ALL existing state (KV, services, sessions, intentions, ACL) is REPLACED. Cluster briefly unavailable during restore.","kind":"exec","risk":"critical","side_effects":["All current Raft state is replaced.","KV, services, sessions, ACLs, intentions all swap to snapshot contents.","Brief outage during application.","Cannot be undone without another snapshot."],"args":[{"name":"path","type":"string","required":true,"description":"Snapshot file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Restore from backup","args":{"path":"/var/backups/consul-pre-migration.snap"}}],"search_terms":[],"command":{"binary":"consul","argv":["snapshot","restore","{{ args.path }}"]}},{"id":"consul.snapshot_save","title":"consul snapshot save <path>","summary":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","description":"Write a Raft snapshot to a local file. Use before risky operations + as a backup.","kind":"exec","risk":"medium","side_effects":["One read of the entire state store.","File written at the configured path on the runner host.","Brief leader IO; no service impact."],"args":[{"name":"path","type":"string","required":true,"description":"Destination file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}\\.snap$","allowed_prefixes":["/var/lib/consul","/var/backups","/opt","/tmp"]}}],"examples":[{"title":"Pre-migration snap","args":{"path":"/var/backups/consul-pre-migration.snap"}}],"search_terms":["cluster backup"],"command":{"binary":"consul","argv":["snapshot","save","{{ args.path }}"]}}]}],"retired_below":"0.2.25"},{"id":"databricks","name":"Databricks","version":"0.1.4","description":"Look up data and run day-2 operations in a Databricks workspace over its REST API: run a bounded read-only SQL statement on a SQL warehouse, browse Unity Catalog down to a table's columns, read the datasets behind an AI/BI dashboard, watch job runs and fetch a failed run's error output, and start, stop, or restart the compute — warehouses, jobs, and clusters — through emisar's policy and approval path instead of the workspace UI.","vendor":"emisar","homepage":"https://emisar.dev/packs/databricks","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/databricks","content_hash":"sha256:b94d861872205dc6f03d3985bbbfd6167c258237a5eaafbfcd8a315e1590cb7b","tarball_url":"https://registry.emisar.dev/v1/packs/databricks/0.1.4/b94d861872205dc6f03d3985bbbfd6167c258237a5eaafbfcd8a315e1590cb7b/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Calls the Databricks workspace REST API over HTTPS with curl, sending the token in an Authorization: Bearer header read from `DATABRICKS_TOKEN` and the workspace URL from `DATABRICKS_HOST`, so allowlist both variables in `inherit_env`.","env":[{"name":"DATABRICKS_HOST","required":true,"description":"Workspace URL, scheme included — the host you open the workspace UI on.","example":"https://1234567890123456.7.gcp.databricks.com"},{"name":"DATABRICKS_TOKEN","required":true,"description":"API token sent as the Bearer credential: a service principal's OAuth token or personal access token. Scope it to what you want reachable — the read actions need CAN USE on the warehouse plus USE CATALOG, USE SCHEMA, and SELECT on the data; the compute and job actions need the matching CAN MANAGE RUN / CAN RESTART permission on each resource."}],"notes":["Generate a personal access token in the workspace under Settings → Developer → Access tokens. A service principal is created in the account console under User management → Service principals, and its OAuth secret is issued there.","Any Databricks env var you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so a variable present on the host but not allowlisted is silently dropped and every action fails auth.","databricks.sql_query only accepts a single statement whose first keyword is SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN. That guard is a guardrail against accidental writes, not a security boundary — the warehouse enforces exactly what the token's grants allow, so scope the token read-only if reads are all you mean to allow.","The token can do everything these actions expose, so let emisar policy decide who may reach the mutating actions: job_run_now and cluster_restart are high risk and need approval under the default policy.","Needs curl 7.76 or newer: the actions use --fail-with-body so a rejected request reports the API's error document instead of failing with empty output."],"verify":"databricks.whoami"},"actions":[{"id":"databricks.catalogs_list","title":"GET /unity-catalog/catalogs","summary":"List the Unity Catalog catalogs this token can see, with owner and type. The top of the catalog.schema.table hierarchy — start here when you need to find where a dataset lives.","description":"List the Unity Catalog catalogs this token can see, with owner and type. The top of the catalog.schema.table hierarchy — start here when you need to find where a dataset lives.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":10,"description":"Catalogs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"First page of catalogs","args":{}}],"search_terms":["list databricks catalogs","browse unity catalog"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"catalogs":{"items":{"additionalProperties":false,"properties":{"catalog_type":{"maxLength":40,"type":"string"},"comment":{"maxLength":40,"type":"string"},"created_at":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"owner":{"maxLength":40,"type":"string"}},"required":["name","catalog_type","owner","comment","created_at"],"type":"object"},"maxItems":10,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["catalogs","next_page_cursor"],"type":"object"}},{"id":"databricks.cluster_events","title":"POST /clusters/events","summary":"List one cluster's recent lifecycle events, newest first — starts, resizes, driver health, termination causes — the timeline for diagnosing why a cluster misbehaved. A read that the API happens to serve over POST.","description":"List one cluster's recent lifecycle events, newest first — starts, resizes, driver health, termination causes — the timeline for diagnosing why a cluster misbehaved. A read that the API happens to serve over POST.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the Databricks workspace API; changes nothing.","Read-only."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Events per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Timeline of a flapping cluster","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["cluster event log","cluster timeline","driver not responding"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"events":{"items":{"additionalProperties":false,"properties":{"current_workers":{"type":["integer","null"]},"reason_code":{"maxLength":60,"type":["string","null"]},"target_workers":{"type":["integer","null"]},"timestamp":{"type":["integer","null"]},"type":{"maxLength":48,"type":"string"},"user":{"maxLength":40,"type":["string","null"]}},"required":["timestamp","type","user","reason_code","current_workers","target_workers"],"type":"object"},"maxItems":12,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["events","next_page_cursor"],"type":"object"}},{"id":"databricks.cluster_get","title":"GET /clusters/get","summary":"Show one cluster's state in detail — including the termination reason when it is down, which is the first thing to read when a cluster died. Follow a suspicious termination with databricks.cluster_events for the timeline.","description":"Show one cluster's state in detail — including the termination reason when it is down, which is the first thing to read when a cluster died. Follow a suspicious termination with databricks.cluster_events for the timeline.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Why the shared cluster went down","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["why did the cluster terminate","cluster state detail"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"autoscale":{"additionalProperties":false,"properties":{"max_workers":{"type":"integer"},"min_workers":{"type":"integer"}},"required":["min_workers","max_workers"],"type":["object","null"]},"autotermination_minutes":{"type":["integer","null"]},"cluster_id":{"maxLength":60,"type":"string"},"creator":{"maxLength":40,"type":["string","null"]},"driver_node_type":{"maxLength":30,"type":["string","null"]},"name":{"maxLength":60,"type":"string"},"node_type":{"maxLength":30,"type":"string"},"num_workers":{"type":["integer","null"]},"source":{"maxLength":24,"type":"string"},"spark_version":{"maxLength":30,"type":"string"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"},"terminated_time":{"type":["integer","null"]},"termination_reason":{"additionalProperties":false,"properties":{"code":{"maxLength":60,"type":"string"},"type":{"maxLength":24,"type":["string","null"]}},"required":["code","type"],"type":["object","null"]}},"required":["cluster_id","name","state","state_message","spark_version","node_type","driver_node_type","num_workers","autoscale","autotermination_minutes","creator","source","start_time","terminated_time","termination_reason"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.cluster_restart","title":"POST /clusters/restart","summary":"Restart a running cluster — the fix for a wedged driver or a leaking Spark context. Everything attached dies with it: running notebooks lose their state and jobs executing on the cluster fail. The API returns before the restart completes; poll databricks.cluster_get until RUNNING again. A cluster that is not RUNNING is left untouched (the API treats that as a no-op).","description":"Restart a running cluster — the fix for a wedged driver or a leaking Spark context. Everything attached dies with it: running notebooks lose their state and jobs executing on the cluster fail. The API returns before the restart completes; poll databricks.cluster_get until RUNNING again. A cluster that is not RUNNING is left untouched (the API treats that as a no-op).","kind":"script","risk":"high","side_effects":["Kills every notebook session and job running on the cluster.","Asynchronous — returns before the cluster is back to RUNNING.","No-op when the cluster is not RUNNING."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Restart the cluster whose driver stopped responding","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["restart cluster","driver unresponsive fix"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"}},"required":["cluster_id","name","state","state_message"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.cluster_start","title":"POST /clusters/start","summary":"Start a terminated all-purpose cluster with its previous configuration. The API returns before the cluster is up — the reported state is usually PENDING; poll databricks.cluster_get until RUNNING. A cluster that is not TERMINATED is left untouched (the API treats that as a no-op), and job-launched clusters cannot be started.","description":"Start a terminated all-purpose cluster with its previous configuration. The API returns before the cluster is up — the reported state is usually PENDING; poll databricks.cluster_get until RUNNING. A cluster that is not TERMINATED is left untouched (the API treats that as a no-op), and job-launched clusters cannot be started.","kind":"script","risk":"medium","side_effects":["Starts billable cluster compute.","Asynchronous — returns before the cluster reaches RUNNING.","No-op when the cluster is not TERMINATED."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Start the analytics cluster before working hours","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["start cluster","bring cluster back up"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"}},"required":["cluster_id","name","state","state_message"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.clusters_list","title":"GET /clusters/list","summary":"List the workspace's all-purpose and job clusters with state, Spark version, and sizing. Filter by state to see only what is RUNNING — or what died in ERROR.","description":"List the workspace's all-purpose and job clusters with state, Spark version, and sizing. Filter by state to see only what is RUNNING — or what died in ERROR.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"state","type":"string","required":false,"default":"","description":"Only clusters in this state; empty means all.","validation":{"pattern":"^(|PENDING|RUNNING|RESTARTING|RESIZING|TERMINATING|TERMINATED|ERROR|UNKNOWN)$","max_length":24}},{"name":"page_size","type":"integer","required":false,"default":8,"description":"Clusters per page.","validation":{"min":1,"max":8}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Only what is currently running","args":{"state":"RUNNING"}}],"search_terms":["list databricks clusters","running clusters"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"clusters":{"items":{"additionalProperties":false,"properties":{"autoscale":{"additionalProperties":false,"properties":{"max_workers":{"type":"integer"},"min_workers":{"type":"integer"}},"required":["min_workers","max_workers"],"type":["object","null"]},"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"node_type":{"maxLength":24,"type":"string"},"num_workers":{"type":["integer","null"]},"source":{"maxLength":24,"type":"string"},"spark_version":{"maxLength":24,"type":"string"},"state":{"maxLength":24,"type":"string"}},"required":["cluster_id","name","state","spark_version","node_type","num_workers","autoscale","source"],"type":"object"},"maxItems":8,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["clusters","next_page_cursor"],"type":"object"}},{"id":"databricks.dashboard_get","title":"GET /lakeview/dashboards/<id>","summary":"Show what one AI/BI (Lakeview) dashboard is made of: its pages, and each dataset behind it with the dataset's parameter keywords. The dataset names here are what databricks.dashboard_sql takes to fetch the actual SQL, and the warehouse_id is where that SQL runs.","description":"Show what one AI/BI (Lakeview) dashboard is made of: its pages, and each dataset behind it with the dataset's parameter keywords. The dataset names here are what databricks.dashboard_sql takes to fetch the actual SQL, and the warehouse_id is where that SQL runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"dashboard_id","type":"string","required":true,"description":"Dashboard ID, from databricks.dashboards_list or the dashboard's /dashboardsv3/<id> URL.","validation":{"pattern":"^[A-Za-z0-9-]{16,40}$","max_length":40}}],"examples":[{"title":"Datasets behind a dashboard from its URL","args":{"dashboard_id":"01f0138fd0d11a23822c3f6384e6c484"}}],"search_terms":["what feeds this dashboard","dashboard datasets","dashboard pages"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboard":{"additionalProperties":false,"properties":{"create_time":{"maxLength":40,"type":"string"},"dashboard_id":{"maxLength":40,"type":"string"},"datasets":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"},"parameter_keywords":{"items":{"maxLength":24,"type":"string"},"maxItems":4,"type":"array"}},"required":["name","display_name","parameter_keywords"],"type":"object"},"maxItems":10,"type":"array"},"datasets_omitted":{"type":"integer"},"display_name":{"maxLength":60,"type":"string"},"lifecycle_state":{"maxLength":24,"type":"string"},"pages":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"}},"required":["name","display_name"],"type":"object"},"maxItems":6,"type":"array"},"pages_omitted":{"type":"integer"},"path":{"maxLength":80,"type":["string","null"]},"update_time":{"maxLength":40,"type":"string"},"warehouse_id":{"maxLength":40,"type":["string","null"]}},"required":["dashboard_id","display_name","lifecycle_state","create_time","update_time","warehouse_id","path","datasets","datasets_omitted","pages","pages_omitted"],"type":"object"}},"required":["dashboard"],"type":"object"}},{"id":"databricks.dashboard_sql","title":"GET /lakeview/dashboards/<id> dataset SQL","summary":"Show the SQL behind one dataset of an AI/BI (Lakeview) dashboard, with the dataset's parameters. The query may contain :parameter markers — replace each with a literal value before re-running it through databricks.sql_query on the dashboard's warehouse. Get dataset names from databricks.dashboard_get; the name and the display name both match.","description":"Show the SQL behind one dataset of an AI/BI (Lakeview) dashboard, with the dataset's parameters. The query may contain :parameter markers — replace each with a literal value before re-running it through databricks.sql_query on the dashboard's warehouse. Get dataset names from databricks.dashboard_get; the name and the display name both match.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"dashboard_id","type":"string","required":true,"description":"Dashboard ID, from databricks.dashboards_list or the dashboard's /dashboardsv3/<id> URL.","validation":{"pattern":"^[A-Za-z0-9-]{16,40}$","max_length":40}},{"name":"dataset","type":"string","required":true,"description":"Dataset name or display name, from databricks.dashboard_get.","validation":{"max_length":120}}],"examples":[{"title":"The SQL feeding a dashboard's main dataset","args":{"dashboard_id":"01f0138fd0d11a23822c3f6384e6c484","dataset":"Daily matches"}}],"search_terms":["sql behind dashboard","dashboard query text","dataset query"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboard_id":{"maxLength":40,"type":"string"},"dataset":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"}},"required":["name","display_name"],"type":"object"},"parameters":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"keyword":{"maxLength":24,"type":"string"}},"required":["keyword","display_name"],"type":"object"},"maxItems":6,"type":"array"},"sql":{"maxLength":2800,"type":"string"},"sql_bytes_total":{"type":"integer"},"sql_truncated":{"type":"boolean"}},"required":["dashboard_id","dataset","sql","sql_bytes_total","sql_truncated","parameters"],"type":"object"}},{"id":"databricks.dashboards_list","title":"GET /lakeview/dashboards","summary":"List the workspace's AI/BI (Lakeview) dashboards with their lifecycle state and default warehouse. Use it to find the dashboard ID that databricks.dashboard_get and databricks.dashboard_sql take — the same ID that appears in a dashboard's /dashboardsv3/<id> URL.","description":"List the workspace's AI/BI (Lakeview) dashboards with their lifecycle state and default warehouse. Use it to find the dashboard ID that databricks.dashboard_get and databricks.dashboard_sql take — the same ID that appears in a dashboard's /dashboardsv3/<id> URL.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":12,"description":"Dashboards per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"First page of dashboards","args":{}}],"search_terms":["list databricks dashboards","find dashboard id"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboards":{"items":{"additionalProperties":false,"properties":{"create_time":{"maxLength":40,"type":"string"},"dashboard_id":{"maxLength":40,"type":"string"},"display_name":{"maxLength":60,"type":"string"},"lifecycle_state":{"maxLength":24,"type":"string"},"warehouse_id":{"maxLength":40,"type":["string","null"]}},"required":["dashboard_id","display_name","lifecycle_state","create_time","warehouse_id"],"type":"object"},"maxItems":12,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["dashboards","next_page_cursor"],"type":"object"}},{"id":"databricks.job_get","title":"GET /jobs/get","summary":"Show one job's definition: its schedule, task graph with each task's kind and dependencies, and the job-level parameters with their defaults — what you review before triggering databricks.job_run_now.","description":"Show one job's definition: its schedule, task graph with each task's kind and dependencies, and the job-level parameters with their defaults — what you review before triggering databricks.job_run_now.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job ID, from databricks.jobs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Review the nightly ETL job before running it","args":{"job_id":947381205673284}}],"search_terms":["job schedule and tasks","show workflow definition","job parameters"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"job":{"additionalProperties":false,"properties":{"creator":{"maxLength":60,"type":["string","null"]},"job_id":{"type":"integer"},"max_concurrent_runs":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"parameters":{"items":{"additionalProperties":false,"properties":{"default":{"maxLength":40,"type":"string"},"name":{"maxLength":30,"type":"string"}},"required":["name","default"],"type":"object"},"maxItems":8,"type":"array"},"run_as":{"maxLength":60,"type":["string","null"]},"schedule":{"additionalProperties":false,"properties":{"cron":{"maxLength":60,"type":"string"},"paused":{"type":"boolean"},"timezone":{"maxLength":30,"type":"string"}},"required":["cron","timezone","paused"],"type":["object","null"]},"tasks":{"items":{"additionalProperties":false,"properties":{"depends_on":{"items":{"maxLength":40,"type":"string"},"maxItems":2,"type":"array"},"kind":{"maxLength":24,"type":"string"},"task_key":{"maxLength":40,"type":"string"}},"required":["task_key","kind","depends_on"],"type":"object"},"maxItems":12,"type":"array"},"tasks_omitted":{"type":"integer"}},"required":["job_id","name","creator","run_as","max_concurrent_runs","schedule","parameters","tasks","tasks_omitted"],"type":"object"}},"required":["job"],"type":"object"}},{"id":"databricks.job_run_cancel","title":"POST /jobs/runs/cancel","summary":"Cancel a running job run — or a single task run — and report the state it reached. Cancellation is asynchronous: the reported state is often still TERMINATING; poll databricks.job_run_get until it settles. The job itself stays defined and can be run again.","description":"Cancel a running job run — or a single task run — and report the state it reached. Cancellation is asynchronous: the reported state is often still TERMINATING; poll databricks.job_run_get until it settles. The job itself stays defined and can be run again.","kind":"script","risk":"medium","side_effects":["Interrupts the run's tasks; a task stopped mid-write leaves whatever its own code leaves.","Asynchronous — the run may still be terminating when this returns."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Run ID, from databricks.job_runs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Stop a run stuck on a dead cluster","args":{"run_id":738495610284753}}],"search_terms":["cancel job run","stop stuck workflow"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","state","result"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"databricks.job_run_get","title":"GET /jobs/runs/get","summary":"Show one job run's state and its per-task breakdown — which task failed, each task's own run_id, and how long each took. A failed task's run_id is what databricks.job_run_output takes for the error detail.","description":"Show one job run's state and its per-task breakdown — which task failed, each task's own run_id, and how long each took. A failed task's run_id is what databricks.job_run_output takes for the error detail.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Job run ID, from databricks.job_runs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Break a failed run down by task","args":{"run_id":738495610284753}}],"search_terms":["which task failed","job run status","task run ids"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"end_time":{"type":["integer","null"]},"job_id":{"type":"integer"},"message":{"maxLength":100,"type":"string"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"run_name":{"maxLength":60,"type":"string"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"tasks":{"items":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"task_key":{"maxLength":40,"type":"string"}},"required":["task_key","run_id","state","result","duration_ms"],"type":"object"},"maxItems":10,"type":"array"},"tasks_omitted":{"type":"integer"}},"required":["run_id","job_id","run_name","state","result","message","start_time","end_time","duration_ms","tasks","tasks_omitted"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"databricks.job_run_now","title":"POST /jobs/run-now","summary":"Trigger a run of an existing job now, optionally overriding its job-level parameters. This executes whatever the job's tasks are defined to do — including writes to production tables — so review the definition with databricks.job_get first. Returns the new run's ID and state; follow it with databricks.job_run_get.","description":"Trigger a run of an existing job now, optionally overriding its job-level parameters. This executes whatever the job's tasks are defined to do — including writes to production tables — so review the definition with databricks.job_get first. Returns the new run's ID and state; follow it with databricks.job_run_get.","kind":"script","risk":"high","side_effects":["Executes the job's workload — may read and write production data.","Starts or consumes job compute, which is billed.","The run continues after this action returns."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job ID, from databricks.jobs_list.","validation":{"min":1,"max":9007199254740991}},{"name":"job_params","type":"string_array","required":false,"default":[],"description":"Job-level parameter overrides as name=value pairs, for parameters the job declares (see databricks.job_get).","validation":{"max_items":32,"max_length":512}},{"name":"idempotency_key","type":"string","required":false,"default":"","description":"Token guaranteeing exactly one launched run — a retry with the same token returns the existing run instead of launching another.","validation":{"max_length":64}}],"examples":[{"title":"Re-run the nightly ETL for one date","args":{"idempotency_key":"emisar-backfill-2026-08-10","job_id":947381205673284,"job_params":["run_date=2026-08-10"]}}],"search_terms":["trigger job run","run workflow now","rerun the etl"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"job_id":{"type":"integer"},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","job_id","state"],"type":"object"}},{"id":"databricks.job_run_output","title":"GET /jobs/runs/get-output","summary":"Show why one task run failed: the error, a bounded tail of its error trace and logs, and the notebook's exit value if it set one. Takes a TASK run's ID — get it from the tasks list in databricks.job_run_get, not the job run's own ID.","description":"Show why one task run failed: the error, a bounded tail of its error trace and logs, and the notebook's exit value if it set one. Takes a TASK run's ID — get it from the tasks list in databricks.job_run_get, not the job run's own ID.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Log and error content is arbitrary task output, returned to the model."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Task run ID, from the tasks list of databricks.job_run_get.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Error detail for the failed ingest task","args":{"run_id":738495610284754}}],"search_terms":["why did the task fail","job run error trace","notebook output"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"error":{"maxLength":150,"type":["string","null"]},"error_trace_tail":{"items":{"maxLength":80,"type":"string"},"maxItems":10,"type":"array"},"logs_tail":{"items":{"maxLength":80,"type":"string"},"maxItems":6,"type":"array"},"logs_truncated":{"type":"boolean"},"notebook_result":{"maxLength":200,"type":["string","null"]},"notebook_result_truncated":{"type":"boolean"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","state","result","error","error_trace_tail","logs_tail","logs_truncated","notebook_result","notebook_result_truncated"],"type":"object"}},{"id":"databricks.job_runs_list","title":"GET /jobs/runs/list","summary":"List recent job runs, newest first — the workspace-wide \"what ran and what failed\" view. Filter to one job with job_id, or to only active or only completed runs. Each run's result code says why it ended; dig into one run with databricks.job_run_get.","description":"List recent job runs, newest first — the workspace-wide \"what ran and what failed\" view. Filter to one job with job_id, or to only active or only completed runs. Each run's result code says why it ended; dig into one run with databricks.job_run_get.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"job_id","type":"integer","required":false,"default":0,"description":"Only this job's runs; 0 means runs from all jobs.","validation":{"min":0,"max":9007199254740991}},{"name":"active_only","type":"boolean","required":false,"default":false,"description":"Only queued, pending, or running runs."},{"name":"completed_only","type":"boolean","required":false,"default":false,"description":"Only finished runs."},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Runs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"What failed recently, workspace-wide","args":{"completed_only":true}},{"title":"Runs of one job","args":{"job_id":947381205673284}}],"search_terms":["recent job runs","failed job runs","is the job still running"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"job_id":{"type":"integer"},"message":{"maxLength":60,"type":"string"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"}},"required":["run_id","job_id","state","result","message","start_time","duration_ms"],"type":"object"},"maxItems":10,"type":"array"}},"required":["runs","next_page_cursor"],"type":"object"}},{"id":"databricks.jobs_list","title":"GET /jobs/list","summary":"List the workspace's jobs (workflows) with their creator. Use the name filter to find one job by its exact, case-insensitive name; the job_id here is what the run actions take.","description":"List the workspace's jobs (workflows) with their creator. Use the name filter to find one job by its exact, case-insensitive name; the job_id here is what the run actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"name","type":"string","required":false,"default":"","description":"Filter on the exact (case-insensitive) job name.","validation":{"max_length":100}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Jobs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Find the nightly ETL job","args":{"name":"nightly-etl"}}],"search_terms":["list databricks jobs","find workflow by name"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"jobs":{"items":{"additionalProperties":false,"properties":{"created_time":{"type":["integer","null"]},"creator":{"maxLength":60,"type":"string"},"job_id":{"type":"integer"},"name":{"maxLength":60,"type":"string"}},"required":["job_id","name","creator","created_time"],"type":"object"},"maxItems":10,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["jobs","next_page_cursor"],"type":"object"}},{"id":"databricks.schemas_list","title":"GET /unity-catalog/schemas","summary":"List the schemas inside one Unity Catalog catalog. The middle level of the catalog.schema.table hierarchy, between databricks.catalogs_list and databricks.tables_list.","description":"List the schemas inside one Unity Catalog catalog. The middle level of the catalog.schema.table hierarchy, between databricks.catalogs_list and databricks.tables_list.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"catalog","type":"string","required":true,"description":"Catalog name, from databricks.catalogs_list.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Schemas per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Schemas in the analytics catalog","args":{"catalog":"analytics"}}],"search_terms":["list schemas in catalog","databricks databases"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"schemas":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":40,"type":"string"},"created_at":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"owner":{"maxLength":40,"type":"string"}},"required":["name","owner","comment","created_at"],"type":"object"},"maxItems":10,"type":"array"}},"required":["schemas","next_page_cursor"],"type":"object"}},{"id":"databricks.sql_query","title":"POST /sql/statements","summary":"Run one read-only SQL statement on a Databricks SQL warehouse and return a bounded slice of the result: column names and types, rows as strings, and honest counts of everything clipped away.","description":"Run one read-only SQL statement on a Databricks SQL warehouse and return a bounded slice of the result: column names and types, rows as strings, and honest counts of everything clipped away. The statement must start with SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN — put a CTE inside a subquery (SELECT ... FROM (WITH ... SELECT ...) q) — and runs with exactly the grants the runner's token holds. If the warehouse is still starting when the wait elapses, the statement keeps running and the returned state is PENDING or RUNNING: poll it with databricks.sql_statement.","kind":"script","risk":"medium","side_effects":["Executes the statement on the warehouse — consumes warehouse compute.","Starts the warehouse if it is auto-stopped.","Result content is arbitrary table data, returned to the model."],"args":[{"name":"sql","type":"string","required":true,"description":"A single read statement (SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN). Use catalog.schema.table names, or set the catalog/schema args.","validation":{"max_length":8192}},{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}},{"name":"catalog","type":"string","required":false,"default":"","description":"Default catalog for unqualified names, like USE CATALOG.","validation":{"pattern":"^[A-Za-z0-9_]*$","max_length":255}},{"name":"schema","type":"string","required":false,"default":"","description":"Default schema for unqualified names, like USE SCHEMA.","validation":{"pattern":"^[A-Za-z0-9_]*$","max_length":255}},{"name":"wait_seconds","type":"integer","required":false,"default":30,"description":"How long the API call waits for the statement to finish.","validation":{"min":5,"max":50}},{"name":"row_limit","type":"integer","required":false,"default":100,"description":"Rows the statement may return before the API truncates it.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Look up yesterday's active users","args":{"sql":"SELECT event_date, count(DISTINCT user_id) AS dau FROM analytics.product.events WHERE event_date >= current_date() - 1 GROUP BY 1 ORDER BY 1","warehouse_id":"1234567890abcdef"}},{"title":"Re-run a dashboard dataset's SQL in its own catalog and schema","args":{"catalog":"analytics","row_limit":50,"schema":"gaming","sql":"SELECT game, count(*) AS matches FROM matches_daily GROUP BY 1 ORDER BY 2 DESC","warehouse_id":"1234567890abcdef"}}],"search_terms":["query databricks table","run sql on warehouse","select from delta table"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"api_truncated":{"type":"boolean"},"columns":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":40,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["name","type"],"type":"object"},"maxItems":16,"type":"array"},"columns_omitted":{"type":"integer"},"rows":{"items":{"items":{"maxLength":60,"type":["string","null"]},"maxItems":16,"type":"array"},"maxItems":1000,"type":"array"},"rows_omitted":{"type":"integer"},"state":{"enum":["PENDING","RUNNING","SUCCEEDED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"},"total_rows":{"type":["integer","null"]}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.sql_statement","title":"GET /sql/statements/<id>","summary":"Check a submitted SQL statement's state and fetch its result once it finished — the poll half of databricks.sql_query for statements that outlived the request's wait. Returns the same bounded result shape.","description":"Check a submitted SQL statement's state and fetch its result once it finished — the poll half of databricks.sql_query for statements that outlived the request's wait. Returns the same bounded result shape.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Result content is arbitrary table data, returned to the model."],"args":[{"name":"statement_id","type":"string","required":true,"description":"Statement ID returned by databricks.sql_query.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Poll a statement that was still running","args":{"statement_id":"01f01390-a2b3-1c4d-9e8f-7a6b5c4d3e2f"}}],"search_terms":["poll sql statement","fetch query result"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"api_truncated":{"type":"boolean"},"columns":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":40,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["name","type"],"type":"object"},"maxItems":16,"type":"array"},"columns_omitted":{"type":"integer"},"rows":{"items":{"items":{"maxLength":60,"type":["string","null"]},"maxItems":16,"type":"array"},"maxItems":1000,"type":"array"},"rows_omitted":{"type":"integer"},"state":{"enum":["PENDING","RUNNING","SUCCEEDED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"},"total_rows":{"type":["integer","null"]}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.sql_statement_cancel","title":"POST /sql/statements/<id>/cancel","summary":"Cancel a running SQL statement so it stops consuming the warehouse, then report the state the statement actually reached. Cancellation is best-effort: a statement that finished first reports its terminal state instead.","description":"Cancel a running SQL statement so it stops consuming the warehouse, then report the state the statement actually reached. Cancellation is best-effort: a statement that finished first reports its terminal state instead.","kind":"script","risk":"medium","side_effects":["Stops the statement's execution on the warehouse.","A statement that already finished is left as it ended."],"args":[{"name":"statement_id","type":"string","required":true,"description":"Statement ID returned by databricks.sql_query.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Cancel a statement stuck on a cold warehouse","args":{"statement_id":"01f01390-a2b3-1c4d-9e8f-7a6b5c4d3e2f"}}],"search_terms":["cancel sql statement","stop runaway query"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"state":{"enum":["PENDING","RUNNING","SUCCEEDED","FAILED","CANCELED","CLOSED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.table_get","title":"GET /unity-catalog/tables/<full_name>","summary":"Show one Unity Catalog table's shape: columns with their SQL types and nullability, the table type and storage format, and — for a view — the defining SQL. What you read before writing a databricks.sql_query against an unfamiliar table.","description":"Show one Unity Catalog table's shape: columns with their SQL types and nullability, the table type and storage format, and — for a view — the defining SQL. What you read before writing a databricks.sql_query against an unfamiliar table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"full_name","type":"string","required":true,"description":"Three-level name, catalog.schema.table.","validation":{"pattern":"^[A-Za-z0-9_]{1,100}\\.[A-Za-z0-9_]{1,100}\\.[A-Za-z0-9_]{1,100}$","max_length":255}}],"examples":[{"title":"Shape of the matches table","args":{"full_name":"analytics.gaming.matches_daily"}}],"search_terms":["table columns and types","describe databricks table","view definition sql"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"table":{"additionalProperties":false,"properties":{"columns":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":24,"type":["string","null"]},"name":{"maxLength":40,"type":"string"},"nullable":{"type":"boolean"},"type":{"maxLength":40,"type":"string"}},"required":["name","type","nullable","comment"],"type":"object"},"maxItems":12,"type":"array"},"columns_omitted":{"type":"integer"},"comment":{"maxLength":60,"type":"string"},"created_at":{"type":["integer","null"]},"data_source_format":{"maxLength":40,"type":["string","null"]},"full_name":{"maxLength":255,"type":"string"},"owner":{"maxLength":40,"type":"string"},"table_type":{"maxLength":40,"type":"string"},"updated_at":{"type":["integer","null"]},"view_definition":{"maxLength":1200,"type":["string","null"]}},"required":["full_name","table_type","data_source_format","owner","comment","created_at","updated_at","view_definition","columns","columns_omitted"],"type":"object"}},"required":["table"],"type":"object"}},{"id":"databricks.tables_list","title":"GET /unity-catalog/tables","summary":"List the tables and views inside one Unity Catalog schema, with each one's type and storage format. Columns are deliberately omitted here — fetch one table's full shape with databricks.table_get.","description":"List the tables and views inside one Unity Catalog schema, with each one's type and storage format. Columns are deliberately omitted here — fetch one table's full shape with databricks.table_get.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"catalog","type":"string","required":true,"description":"Catalog name.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"schema","type":"string","required":true,"description":"Schema name inside the catalog.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Tables per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Tables in analytics.gaming","args":{"catalog":"analytics","schema":"gaming"}}],"search_terms":["list tables in schema","find delta table"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"tables":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":40,"type":"string"},"data_source_format":{"maxLength":40,"type":["string","null"]},"name":{"maxLength":60,"type":"string"},"table_type":{"maxLength":40,"type":"string"},"updated_at":{"type":["integer","null"]}},"required":["name","table_type","data_source_format","comment","updated_at"],"type":"object"},"maxItems":10,"type":"array"}},"required":["tables","next_page_cursor"],"type":"object"}},{"id":"databricks.warehouse_get","title":"GET /sql/warehouses/<id>","summary":"Show one SQL warehouse's state, sizing, and health detail — including the failure summary when the platform reports it degraded. The state to poll after databricks.warehouse_start or databricks.warehouse_stop.","description":"Show one SQL warehouse's state, sizing, and health detail — including the failure summary when the platform reports it degraded. The state to poll after databricks.warehouse_start or databricks.warehouse_stop.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Health of the BI warehouse","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["warehouse health","why is warehouse degraded","warehouse state"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"auto_stop_mins":{"type":"integer"},"cluster_size":{"maxLength":24,"type":"string"},"creator":{"maxLength":60,"type":"string"},"health":{"additionalProperties":false,"properties":{"failure_code":{"maxLength":60,"type":["string","null"]},"status":{"maxLength":24,"type":"string"},"summary":{"maxLength":160,"type":["string","null"]}},"required":["status","summary","failure_code"],"type":["object","null"]},"id":{"maxLength":40,"type":"string"},"max_num_clusters":{"type":"integer"},"min_num_clusters":{"type":"integer"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"serverless":{"type":"boolean"},"state":{"maxLength":24,"type":"string"},"warehouse_type":{"maxLength":24,"type":"string"}},"required":["id","name","state","cluster_size","min_num_clusters","max_num_clusters","num_clusters","auto_stop_mins","serverless","warehouse_type","creator","health"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouse_start","title":"POST /sql/warehouses/<id>/start","summary":"Start a stopped SQL warehouse ahead of the queries that need it, so they skip the cold start. The API returns before the warehouse is up — the reported state is usually STARTING; poll databricks.warehouse_get until RUNNING. Starting a warehouse that is already running is a no-op.","description":"Start a stopped SQL warehouse ahead of the queries that need it, so they skip the cold start. The API returns before the warehouse is up — the reported state is usually STARTING; poll databricks.warehouse_get until RUNNING. Starting a warehouse that is already running is a no-op.","kind":"script","risk":"medium","side_effects":["Starts billable warehouse compute.","Asynchronous — returns before the warehouse reaches RUNNING."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Warm the BI warehouse before a batch of lookups","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["start sql warehouse","warm up warehouse"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["id","name","state","num_clusters"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouse_stop","title":"POST /sql/warehouses/<id>/stop","summary":"Stop a running SQL warehouse to cut its compute spend. Queries running on it are interrupted, and the next statement that arrives auto-starts it again at cold-start latency. The API returns before the warehouse is down — poll databricks.warehouse_get until STOPPED.","description":"Stop a running SQL warehouse to cut its compute spend. Queries running on it are interrupted, and the next statement that arrives auto-starts it again at cold-start latency. The API returns before the warehouse is down — poll databricks.warehouse_get until STOPPED.","kind":"script","risk":"medium","side_effects":["Interrupts queries currently running on the warehouse.","Stops billable compute; the next query pays the cold start.","Asynchronous — returns before the warehouse reaches STOPPED."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Stop an idle warehouse over the weekend","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["stop sql warehouse","cut warehouse cost"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["id","name","state","num_clusters"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouses_list","title":"GET /sql/warehouses","summary":"List the workspace's SQL warehouses with state, size, and health at a glance. The warehouse ID here is what databricks.sql_query runs on; a STOPPED warehouse auto-starts when a statement arrives, at cold-start latency.","description":"List the workspace's SQL warehouses with state, size, and health at a glance. The warehouse ID here is what databricks.sql_query runs on; a STOPPED warehouse auto-starts when a statement arrives, at cold-start latency.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":12,"description":"Warehouses per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"All warehouses and their states","args":{}}],"search_terms":["list sql warehouses","which warehouse is running"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"warehouses":{"items":{"additionalProperties":false,"properties":{"auto_stop_mins":{"type":"integer"},"cluster_size":{"maxLength":24,"type":"string"},"health_status":{"maxLength":24,"type":["string","null"]},"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"serverless":{"type":"boolean"},"state":{"maxLength":24,"type":"string"},"warehouse_type":{"maxLength":24,"type":"string"}},"required":["id","name","state","cluster_size","num_clusters","auto_stop_mins","serverless","warehouse_type","health_status"],"type":"object"},"maxItems":12,"type":"array"}},"required":["warehouses","next_page_cursor"],"type":"object"}},{"id":"databricks.whoami","title":"GET /preview/scim/v2/Me","summary":"Check which Databricks identity the runner's token authenticates as, and that the workspace is reachable at all. Use it first when any other action fails auth, or as the setup verification.","description":"Check which Databricks identity the runner's token authenticates as, and that the workspace is reachable at all. Use it first when any other action fails auth, or as the setup verification.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[],"examples":[{"title":"Verify the workspace connection","args":{}}],"search_terms":["check databricks token","which databricks user"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"active":{"type":"boolean"},"display_name":{"maxLength":80,"type":"string"},"id":{"maxLength":48,"type":"string"},"user_name":{"maxLength":100,"type":"string"}},"required":["id","user_name","display_name","active"],"type":"object"}}],"previous_versions":[{"version":"0.1.3","content_hash":"sha256:0012ca6d06b1004699dab034a64692b5cc33b8510c14821158b9481bc0980844","tarball_url":"https://registry.emisar.dev/v1/packs/databricks/0.1.3/0012ca6d06b1004699dab034a64692b5cc33b8510c14821158b9481bc0980844/pack.tar.gz","actions":[{"id":"databricks.catalogs_list","title":"GET /unity-catalog/catalogs","summary":"List the Unity Catalog catalogs this token can see, with owner and type. The top of the catalog.schema.table hierarchy — start here when you need to find where a dataset lives.","description":"List the Unity Catalog catalogs this token can see, with owner and type. The top of the catalog.schema.table hierarchy — start here when you need to find where a dataset lives.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":10,"description":"Catalogs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"First page of catalogs","args":{}}],"search_terms":["list databricks catalogs","browse unity catalog"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"catalogs":{"items":{"additionalProperties":false,"properties":{"catalog_type":{"maxLength":40,"type":"string"},"comment":{"maxLength":40,"type":"string"},"created_at":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"owner":{"maxLength":40,"type":"string"}},"required":["name","catalog_type","owner","comment","created_at"],"type":"object"},"maxItems":10,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["catalogs","next_page_cursor"],"type":"object"}},{"id":"databricks.cluster_events","title":"POST /clusters/events","summary":"List one cluster's recent lifecycle events, newest first — starts, resizes, driver health, termination causes — the timeline for diagnosing why a cluster misbehaved. A read that the API happens to serve over POST.","description":"List one cluster's recent lifecycle events, newest first — starts, resizes, driver health, termination causes — the timeline for diagnosing why a cluster misbehaved. A read that the API happens to serve over POST.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the Databricks workspace API; changes nothing.","Read-only."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Events per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Timeline of a flapping cluster","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["cluster event log","cluster timeline","driver not responding"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"events":{"items":{"additionalProperties":false,"properties":{"current_workers":{"type":["integer","null"]},"reason_code":{"maxLength":60,"type":["string","null"]},"target_workers":{"type":["integer","null"]},"timestamp":{"type":["integer","null"]},"type":{"maxLength":48,"type":"string"},"user":{"maxLength":40,"type":["string","null"]}},"required":["timestamp","type","user","reason_code","current_workers","target_workers"],"type":"object"},"maxItems":12,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["events","next_page_cursor"],"type":"object"}},{"id":"databricks.cluster_get","title":"GET /clusters/get","summary":"Show one cluster's state in detail — including the termination reason when it is down, which is the first thing to read when a cluster died. Follow a suspicious termination with databricks.cluster_events for the timeline.","description":"Show one cluster's state in detail — including the termination reason when it is down, which is the first thing to read when a cluster died. Follow a suspicious termination with databricks.cluster_events for the timeline.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Why the shared cluster went down","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["why did the cluster terminate","cluster state detail"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"autoscale":{"additionalProperties":false,"properties":{"max_workers":{"type":"integer"},"min_workers":{"type":"integer"}},"required":["min_workers","max_workers"],"type":["object","null"]},"autotermination_minutes":{"type":["integer","null"]},"cluster_id":{"maxLength":60,"type":"string"},"creator":{"maxLength":40,"type":["string","null"]},"driver_node_type":{"maxLength":30,"type":["string","null"]},"name":{"maxLength":60,"type":"string"},"node_type":{"maxLength":30,"type":"string"},"num_workers":{"type":["integer","null"]},"source":{"maxLength":24,"type":"string"},"spark_version":{"maxLength":30,"type":"string"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"},"terminated_time":{"type":["integer","null"]},"termination_reason":{"additionalProperties":false,"properties":{"code":{"maxLength":60,"type":"string"},"type":{"maxLength":24,"type":["string","null"]}},"required":["code","type"],"type":["object","null"]}},"required":["cluster_id","name","state","state_message","spark_version","node_type","driver_node_type","num_workers","autoscale","autotermination_minutes","creator","source","start_time","terminated_time","termination_reason"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.cluster_restart","title":"POST /clusters/restart","summary":"Restart a running cluster — the fix for a wedged driver or a leaking Spark context. Everything attached dies with it: running notebooks lose their state and jobs executing on the cluster fail. The API returns before the restart completes; poll databricks.cluster_get until RUNNING again. A cluster that is not RUNNING is left untouched (the API treats that as a no-op).","description":"Restart a running cluster — the fix for a wedged driver or a leaking Spark context. Everything attached dies with it: running notebooks lose their state and jobs executing on the cluster fail. The API returns before the restart completes; poll databricks.cluster_get until RUNNING again. A cluster that is not RUNNING is left untouched (the API treats that as a no-op).","kind":"script","risk":"high","side_effects":["Kills every notebook session and job running on the cluster.","Asynchronous — returns before the cluster is back to RUNNING.","No-op when the cluster is not RUNNING."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Restart the cluster whose driver stopped responding","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["restart cluster","driver unresponsive fix"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"}},"required":["cluster_id","name","state","state_message"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.cluster_start","title":"POST /clusters/start","summary":"Start a terminated all-purpose cluster with its previous configuration. The API returns before the cluster is up — the reported state is usually PENDING; poll databricks.cluster_get until RUNNING. A cluster that is not TERMINATED is left untouched (the API treats that as a no-op), and job-launched clusters cannot be started.","description":"Start a terminated all-purpose cluster with its previous configuration. The API returns before the cluster is up — the reported state is usually PENDING; poll databricks.cluster_get until RUNNING. A cluster that is not TERMINATED is left untouched (the API treats that as a no-op), and job-launched clusters cannot be started.","kind":"script","risk":"medium","side_effects":["Starts billable cluster compute.","Asynchronous — returns before the cluster reaches RUNNING.","No-op when the cluster is not TERMINATED."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Start the analytics cluster before working hours","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["start cluster","bring cluster back up"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"}},"required":["cluster_id","name","state","state_message"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.clusters_list","title":"GET /clusters/list","summary":"List the workspace's all-purpose and job clusters with state, Spark version, and sizing. Filter by state to see only what is RUNNING — or what died in ERROR.","description":"List the workspace's all-purpose and job clusters with state, Spark version, and sizing. Filter by state to see only what is RUNNING — or what died in ERROR.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"state","type":"string","required":false,"default":"","description":"Only clusters in this state; empty means all.","validation":{"pattern":"^(|PENDING|RUNNING|RESTARTING|RESIZING|TERMINATING|TERMINATED|ERROR|UNKNOWN)$","max_length":24}},{"name":"page_size","type":"integer","required":false,"default":8,"description":"Clusters per page.","validation":{"min":1,"max":8}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Only what is currently running","args":{"state":"RUNNING"}}],"search_terms":["list databricks clusters","running clusters"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"clusters":{"items":{"additionalProperties":false,"properties":{"autoscale":{"additionalProperties":false,"properties":{"max_workers":{"type":"integer"},"min_workers":{"type":"integer"}},"required":["min_workers","max_workers"],"type":["object","null"]},"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"node_type":{"maxLength":24,"type":"string"},"num_workers":{"type":["integer","null"]},"source":{"maxLength":24,"type":"string"},"spark_version":{"maxLength":24,"type":"string"},"state":{"maxLength":24,"type":"string"}},"required":["cluster_id","name","state","spark_version","node_type","num_workers","autoscale","source"],"type":"object"},"maxItems":8,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["clusters","next_page_cursor"],"type":"object"}},{"id":"databricks.dashboard_get","title":"GET /lakeview/dashboards/<id>","summary":"Show what one AI/BI (Lakeview) dashboard is made of: its pages, and each dataset behind it with the dataset's parameter keywords. The dataset names here are what databricks.dashboard_sql takes to fetch the actual SQL, and the warehouse_id is where that SQL runs.","description":"Show what one AI/BI (Lakeview) dashboard is made of: its pages, and each dataset behind it with the dataset's parameter keywords. The dataset names here are what databricks.dashboard_sql takes to fetch the actual SQL, and the warehouse_id is where that SQL runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"dashboard_id","type":"string","required":true,"description":"Dashboard ID, from databricks.dashboards_list or the dashboard's /dashboardsv3/<id> URL.","validation":{"pattern":"^[A-Za-z0-9-]{16,40}$","max_length":40}}],"examples":[{"title":"Datasets behind a dashboard from its URL","args":{"dashboard_id":"01f0138fd0d11a23822c3f6384e6c484"}}],"search_terms":["what feeds this dashboard","dashboard datasets","dashboard pages"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboard":{"additionalProperties":false,"properties":{"create_time":{"maxLength":40,"type":"string"},"dashboard_id":{"maxLength":40,"type":"string"},"datasets":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"},"parameter_keywords":{"items":{"maxLength":24,"type":"string"},"maxItems":4,"type":"array"}},"required":["name","display_name","parameter_keywords"],"type":"object"},"maxItems":10,"type":"array"},"datasets_omitted":{"type":"integer"},"display_name":{"maxLength":60,"type":"string"},"lifecycle_state":{"maxLength":24,"type":"string"},"pages":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"}},"required":["name","display_name"],"type":"object"},"maxItems":6,"type":"array"},"pages_omitted":{"type":"integer"},"path":{"maxLength":80,"type":["string","null"]},"update_time":{"maxLength":40,"type":"string"},"warehouse_id":{"maxLength":40,"type":["string","null"]}},"required":["dashboard_id","display_name","lifecycle_state","create_time","update_time","warehouse_id","path","datasets","datasets_omitted","pages","pages_omitted"],"type":"object"}},"required":["dashboard"],"type":"object"}},{"id":"databricks.dashboard_sql","title":"GET /lakeview/dashboards/<id> dataset SQL","summary":"Show the SQL behind one dataset of an AI/BI (Lakeview) dashboard, with the dataset's parameters. The query may contain :parameter markers — replace each with a literal value before re-running it through databricks.sql_query on the dashboard's warehouse. Get dataset names from databricks.dashboard_get; the name and the display name both match.","description":"Show the SQL behind one dataset of an AI/BI (Lakeview) dashboard, with the dataset's parameters. The query may contain :parameter markers — replace each with a literal value before re-running it through databricks.sql_query on the dashboard's warehouse. Get dataset names from databricks.dashboard_get; the name and the display name both match.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"dashboard_id","type":"string","required":true,"description":"Dashboard ID, from databricks.dashboards_list or the dashboard's /dashboardsv3/<id> URL.","validation":{"pattern":"^[A-Za-z0-9-]{16,40}$","max_length":40}},{"name":"dataset","type":"string","required":true,"description":"Dataset name or display name, from databricks.dashboard_get.","validation":{"max_length":120}}],"examples":[{"title":"The SQL feeding a dashboard's main dataset","args":{"dashboard_id":"01f0138fd0d11a23822c3f6384e6c484","dataset":"Daily matches"}}],"search_terms":["sql behind dashboard","dashboard query text","dataset query"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboard_id":{"maxLength":40,"type":"string"},"dataset":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"}},"required":["name","display_name"],"type":"object"},"parameters":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"keyword":{"maxLength":24,"type":"string"}},"required":["keyword","display_name"],"type":"object"},"maxItems":6,"type":"array"},"sql":{"maxLength":2800,"type":"string"},"sql_bytes_total":{"type":"integer"},"sql_truncated":{"type":"boolean"}},"required":["dashboard_id","dataset","sql","sql_bytes_total","sql_truncated","parameters"],"type":"object"}},{"id":"databricks.dashboards_list","title":"GET /lakeview/dashboards","summary":"List the workspace's AI/BI (Lakeview) dashboards with their lifecycle state and default warehouse. Use it to find the dashboard ID that databricks.dashboard_get and databricks.dashboard_sql take — the same ID that appears in a dashboard's /dashboardsv3/<id> URL.","description":"List the workspace's AI/BI (Lakeview) dashboards with their lifecycle state and default warehouse. Use it to find the dashboard ID that databricks.dashboard_get and databricks.dashboard_sql take — the same ID that appears in a dashboard's /dashboardsv3/<id> URL.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":12,"description":"Dashboards per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"First page of dashboards","args":{}}],"search_terms":["list databricks dashboards","find dashboard id"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboards":{"items":{"additionalProperties":false,"properties":{"create_time":{"maxLength":40,"type":"string"},"dashboard_id":{"maxLength":40,"type":"string"},"display_name":{"maxLength":60,"type":"string"},"lifecycle_state":{"maxLength":24,"type":"string"},"warehouse_id":{"maxLength":40,"type":["string","null"]}},"required":["dashboard_id","display_name","lifecycle_state","create_time","warehouse_id"],"type":"object"},"maxItems":12,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["dashboards","next_page_cursor"],"type":"object"}},{"id":"databricks.job_get","title":"GET /jobs/get","summary":"Show one job's definition: its schedule, task graph with each task's kind and dependencies, and the job-level parameters with their defaults — what you review before triggering databricks.job_run_now.","description":"Show one job's definition: its schedule, task graph with each task's kind and dependencies, and the job-level parameters with their defaults — what you review before triggering databricks.job_run_now.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job ID, from databricks.jobs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Review the nightly ETL job before running it","args":{"job_id":947381205673284}}],"search_terms":["job schedule and tasks","show workflow definition","job parameters"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"job":{"additionalProperties":false,"properties":{"creator":{"maxLength":60,"type":["string","null"]},"job_id":{"type":"integer"},"max_concurrent_runs":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"parameters":{"items":{"additionalProperties":false,"properties":{"default":{"maxLength":40,"type":"string"},"name":{"maxLength":30,"type":"string"}},"required":["name","default"],"type":"object"},"maxItems":8,"type":"array"},"run_as":{"maxLength":60,"type":["string","null"]},"schedule":{"additionalProperties":false,"properties":{"cron":{"maxLength":60,"type":"string"},"paused":{"type":"boolean"},"timezone":{"maxLength":30,"type":"string"}},"required":["cron","timezone","paused"],"type":["object","null"]},"tasks":{"items":{"additionalProperties":false,"properties":{"depends_on":{"items":{"maxLength":40,"type":"string"},"maxItems":2,"type":"array"},"kind":{"maxLength":24,"type":"string"},"task_key":{"maxLength":40,"type":"string"}},"required":["task_key","kind","depends_on"],"type":"object"},"maxItems":12,"type":"array"},"tasks_omitted":{"type":"integer"}},"required":["job_id","name","creator","run_as","max_concurrent_runs","schedule","parameters","tasks","tasks_omitted"],"type":"object"}},"required":["job"],"type":"object"}},{"id":"databricks.job_run_cancel","title":"POST /jobs/runs/cancel","summary":"Cancel a running job run — or a single task run — and report the state it reached. Cancellation is asynchronous: the reported state is often still TERMINATING; poll databricks.job_run_get until it settles. The job itself stays defined and can be run again.","description":"Cancel a running job run — or a single task run — and report the state it reached. Cancellation is asynchronous: the reported state is often still TERMINATING; poll databricks.job_run_get until it settles. The job itself stays defined and can be run again.","kind":"script","risk":"medium","side_effects":["Interrupts the run's tasks; a task stopped mid-write leaves whatever its own code leaves.","Asynchronous — the run may still be terminating when this returns."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Run ID, from databricks.job_runs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Stop a run stuck on a dead cluster","args":{"run_id":738495610284753}}],"search_terms":["cancel job run","stop stuck workflow"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","state","result"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"databricks.job_run_get","title":"GET /jobs/runs/get","summary":"Show one job run's state and its per-task breakdown — which task failed, each task's own run_id, and how long each took. A failed task's run_id is what databricks.job_run_output takes for the error detail.","description":"Show one job run's state and its per-task breakdown — which task failed, each task's own run_id, and how long each took. A failed task's run_id is what databricks.job_run_output takes for the error detail.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Job run ID, from databricks.job_runs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Break a failed run down by task","args":{"run_id":738495610284753}}],"search_terms":["which task failed","job run status","task run ids"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"end_time":{"type":["integer","null"]},"job_id":{"type":"integer"},"message":{"maxLength":100,"type":"string"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"run_name":{"maxLength":60,"type":"string"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"tasks":{"items":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"task_key":{"maxLength":40,"type":"string"}},"required":["task_key","run_id","state","result","duration_ms"],"type":"object"},"maxItems":10,"type":"array"},"tasks_omitted":{"type":"integer"}},"required":["run_id","job_id","run_name","state","result","message","start_time","end_time","duration_ms","tasks","tasks_omitted"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"databricks.job_run_now","title":"POST /jobs/run-now","summary":"Trigger a run of an existing job now, optionally overriding its job-level parameters. This executes whatever the job's tasks are defined to do — including writes to production tables — so review the definition with databricks.job_get first. Returns the new run's ID and state; follow it with databricks.job_run_get.","description":"Trigger a run of an existing job now, optionally overriding its job-level parameters. This executes whatever the job's tasks are defined to do — including writes to production tables — so review the definition with databricks.job_get first. Returns the new run's ID and state; follow it with databricks.job_run_get.","kind":"script","risk":"high","side_effects":["Executes the job's workload — may read and write production data.","Starts or consumes job compute, which is billed.","The run continues after this action returns."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job ID, from databricks.jobs_list.","validation":{"min":1,"max":9007199254740991}},{"name":"job_params","type":"string_array","required":false,"default":[],"description":"Job-level parameter overrides as name=value pairs, for parameters the job declares (see databricks.job_get).","validation":{"max_items":32,"max_length":512}},{"name":"idempotency_key","type":"string","required":false,"default":"","description":"Token guaranteeing exactly one launched run — a retry with the same token returns the existing run instead of launching another.","validation":{"max_length":64}}],"examples":[{"title":"Re-run the nightly ETL for one date","args":{"idempotency_key":"emisar-backfill-2026-08-10","job_id":947381205673284,"job_params":["run_date=2026-08-10"]}}],"search_terms":["trigger job run","run workflow now","rerun the etl"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"job_id":{"type":"integer"},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","job_id","state"],"type":"object"}},{"id":"databricks.job_run_output","title":"GET /jobs/runs/get-output","summary":"Show why one task run failed: the error, a bounded tail of its error trace and logs, and the notebook's exit value if it set one. Takes a TASK run's ID — get it from the tasks list in databricks.job_run_get, not the job run's own ID.","description":"Show why one task run failed: the error, a bounded tail of its error trace and logs, and the notebook's exit value if it set one. Takes a TASK run's ID — get it from the tasks list in databricks.job_run_get, not the job run's own ID.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Log and error content is arbitrary task output, returned to the model."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Task run ID, from the tasks list of databricks.job_run_get.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Error detail for the failed ingest task","args":{"run_id":738495610284754}}],"search_terms":["why did the task fail","job run error trace","notebook output"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"error":{"maxLength":150,"type":["string","null"]},"error_trace_tail":{"items":{"maxLength":80,"type":"string"},"maxItems":10,"type":"array"},"logs_tail":{"items":{"maxLength":80,"type":"string"},"maxItems":6,"type":"array"},"logs_truncated":{"type":"boolean"},"notebook_result":{"maxLength":200,"type":["string","null"]},"notebook_result_truncated":{"type":"boolean"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","state","result","error","error_trace_tail","logs_tail","logs_truncated","notebook_result","notebook_result_truncated"],"type":"object"}},{"id":"databricks.job_runs_list","title":"GET /jobs/runs/list","summary":"List recent job runs, newest first — the workspace-wide \"what ran and what failed\" view. Filter to one job with job_id, or to only active or only completed runs. Each run's result code says why it ended; dig into one run with databricks.job_run_get.","description":"List recent job runs, newest first — the workspace-wide \"what ran and what failed\" view. Filter to one job with job_id, or to only active or only completed runs. Each run's result code says why it ended; dig into one run with databricks.job_run_get.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"job_id","type":"integer","required":false,"default":0,"description":"Only this job's runs; 0 means runs from all jobs.","validation":{"min":0,"max":9007199254740991}},{"name":"active_only","type":"boolean","required":false,"default":false,"description":"Only queued, pending, or running runs."},{"name":"completed_only","type":"boolean","required":false,"default":false,"description":"Only finished runs."},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Runs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"What failed recently, workspace-wide","args":{"completed_only":true}},{"title":"Runs of one job","args":{"job_id":947381205673284}}],"search_terms":["recent job runs","failed job runs","is the job still running"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"job_id":{"type":"integer"},"message":{"maxLength":60,"type":"string"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"}},"required":["run_id","job_id","state","result","message","start_time","duration_ms"],"type":"object"},"maxItems":10,"type":"array"}},"required":["runs","next_page_cursor"],"type":"object"}},{"id":"databricks.jobs_list","title":"GET /jobs/list","summary":"List the workspace's jobs (workflows) with their creator. Use the name filter to find one job by its exact, case-insensitive name; the job_id here is what the run actions take.","description":"List the workspace's jobs (workflows) with their creator. Use the name filter to find one job by its exact, case-insensitive name; the job_id here is what the run actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"name","type":"string","required":false,"default":"","description":"Filter on the exact (case-insensitive) job name.","validation":{"max_length":100}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Jobs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Find the nightly ETL job","args":{"name":"nightly-etl"}}],"search_terms":["list databricks jobs","find workflow by name"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"jobs":{"items":{"additionalProperties":false,"properties":{"created_time":{"type":["integer","null"]},"creator":{"maxLength":60,"type":"string"},"job_id":{"type":"integer"},"name":{"maxLength":60,"type":"string"}},"required":["job_id","name","creator","created_time"],"type":"object"},"maxItems":10,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["jobs","next_page_cursor"],"type":"object"}},{"id":"databricks.schemas_list","title":"GET /unity-catalog/schemas","summary":"List the schemas inside one Unity Catalog catalog. The middle level of the catalog.schema.table hierarchy, between databricks.catalogs_list and databricks.tables_list.","description":"List the schemas inside one Unity Catalog catalog. The middle level of the catalog.schema.table hierarchy, between databricks.catalogs_list and databricks.tables_list.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"catalog","type":"string","required":true,"description":"Catalog name, from databricks.catalogs_list.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Schemas per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Schemas in the analytics catalog","args":{"catalog":"analytics"}}],"search_terms":["list schemas in catalog","databricks databases"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"schemas":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":40,"type":"string"},"created_at":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"owner":{"maxLength":40,"type":"string"}},"required":["name","owner","comment","created_at"],"type":"object"},"maxItems":10,"type":"array"}},"required":["schemas","next_page_cursor"],"type":"object"}},{"id":"databricks.sql_query","title":"POST /sql/statements","summary":"Run one read-only SQL statement on a Databricks SQL warehouse and return a bounded slice of the result: column names and types, rows as strings, and honest counts of everything clipped away.","description":"Run one read-only SQL statement on a Databricks SQL warehouse and return a bounded slice of the result: column names and types, rows as strings, and honest counts of everything clipped away. The statement must start with SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN — put a CTE inside a subquery (SELECT ... FROM (WITH ... SELECT ...) q) — and runs with exactly the grants the runner's token holds. If the warehouse is still starting when the wait elapses, the statement keeps running and the returned state is PENDING or RUNNING: poll it with databricks.sql_statement.","kind":"script","risk":"medium","side_effects":["Executes the statement on the warehouse — consumes warehouse compute.","Starts the warehouse if it is auto-stopped.","Result content is arbitrary table data, returned to the model."],"args":[{"name":"sql","type":"string","required":true,"description":"A single read statement (SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN). Use catalog.schema.table names, or set the catalog/schema args.","validation":{"max_length":8192}},{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}},{"name":"catalog","type":"string","required":false,"default":"","description":"Default catalog for unqualified names, like USE CATALOG.","validation":{"pattern":"^[A-Za-z0-9_]*$","max_length":255}},{"name":"schema","type":"string","required":false,"default":"","description":"Default schema for unqualified names, like USE SCHEMA.","validation":{"pattern":"^[A-Za-z0-9_]*$","max_length":255}},{"name":"wait_seconds","type":"integer","required":false,"default":30,"description":"How long the API call waits for the statement to finish.","validation":{"min":5,"max":50}},{"name":"row_limit","type":"integer","required":false,"default":100,"description":"Rows the statement may return before the API truncates it.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Look up yesterday's active users","args":{"sql":"SELECT event_date, count(DISTINCT user_id) AS dau FROM analytics.product.events WHERE event_date >= current_date() - 1 GROUP BY 1 ORDER BY 1","warehouse_id":"1234567890abcdef"}},{"title":"Re-run a dashboard dataset's SQL in its own catalog and schema","args":{"catalog":"analytics","row_limit":50,"schema":"gaming","sql":"SELECT game, count(*) AS matches FROM matches_daily GROUP BY 1 ORDER BY 2 DESC","warehouse_id":"1234567890abcdef"}}],"search_terms":["query databricks table","run sql on warehouse","select from delta table"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"api_truncated":{"type":"boolean"},"columns":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":40,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["name","type"],"type":"object"},"maxItems":16,"type":"array"},"columns_omitted":{"type":"integer"},"rows":{"items":{"items":{"maxLength":60,"type":["string","null"]},"maxItems":16,"type":"array"},"maxItems":1000,"type":"array"},"rows_omitted":{"type":"integer"},"state":{"enum":["PENDING","RUNNING","SUCCEEDED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"},"total_rows":{"type":["integer","null"]}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.sql_statement","title":"GET /sql/statements/<id>","summary":"Check a submitted SQL statement's state and fetch its result once it finished — the poll half of databricks.sql_query for statements that outlived the request's wait. Returns the same bounded result shape.","description":"Check a submitted SQL statement's state and fetch its result once it finished — the poll half of databricks.sql_query for statements that outlived the request's wait. Returns the same bounded result shape.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Result content is arbitrary table data, returned to the model."],"args":[{"name":"statement_id","type":"string","required":true,"description":"Statement ID returned by databricks.sql_query.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Poll a statement that was still running","args":{"statement_id":"01f01390-a2b3-1c4d-9e8f-7a6b5c4d3e2f"}}],"search_terms":["poll sql statement","fetch query result"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"api_truncated":{"type":"boolean"},"columns":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":40,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["name","type"],"type":"object"},"maxItems":16,"type":"array"},"columns_omitted":{"type":"integer"},"rows":{"items":{"items":{"maxLength":60,"type":["string","null"]},"maxItems":16,"type":"array"},"maxItems":1000,"type":"array"},"rows_omitted":{"type":"integer"},"state":{"enum":["PENDING","RUNNING","SUCCEEDED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"},"total_rows":{"type":["integer","null"]}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.sql_statement_cancel","title":"POST /sql/statements/<id>/cancel","summary":"Cancel a running SQL statement so it stops consuming the warehouse, then report the state the statement actually reached. Cancellation is best-effort: a statement that finished first reports its terminal state instead.","description":"Cancel a running SQL statement so it stops consuming the warehouse, then report the state the statement actually reached. Cancellation is best-effort: a statement that finished first reports its terminal state instead.","kind":"script","risk":"medium","side_effects":["Stops the statement's execution on the warehouse.","A statement that already finished is left as it ended."],"args":[{"name":"statement_id","type":"string","required":true,"description":"Statement ID returned by databricks.sql_query.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Cancel a statement stuck on a cold warehouse","args":{"statement_id":"01f01390-a2b3-1c4d-9e8f-7a6b5c4d3e2f"}}],"search_terms":["cancel sql statement","stop runaway query"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"state":{"enum":["PENDING","RUNNING","SUCCEEDED","FAILED","CANCELED","CLOSED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.table_get","title":"GET /unity-catalog/tables/<full_name>","summary":"Show one Unity Catalog table's shape: columns with their SQL types and nullability, the table type and storage format, and — for a view — the defining SQL. What you read before writing a databricks.sql_query against an unfamiliar table.","description":"Show one Unity Catalog table's shape: columns with their SQL types and nullability, the table type and storage format, and — for a view — the defining SQL. What you read before writing a databricks.sql_query against an unfamiliar table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"full_name","type":"string","required":true,"description":"Three-level name, catalog.schema.table.","validation":{"pattern":"^[A-Za-z0-9_]{1,100}\\.[A-Za-z0-9_]{1,100}\\.[A-Za-z0-9_]{1,100}$","max_length":255}}],"examples":[{"title":"Shape of the matches table","args":{"full_name":"analytics.gaming.matches_daily"}}],"search_terms":["table columns and types","describe databricks table","view definition sql"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"table":{"additionalProperties":false,"properties":{"columns":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":24,"type":["string","null"]},"name":{"maxLength":40,"type":"string"},"nullable":{"type":"boolean"},"type":{"maxLength":40,"type":"string"}},"required":["name","type","nullable","comment"],"type":"object"},"maxItems":12,"type":"array"},"columns_omitted":{"type":"integer"},"comment":{"maxLength":60,"type":"string"},"created_at":{"type":["integer","null"]},"data_source_format":{"maxLength":40,"type":["string","null"]},"full_name":{"maxLength":255,"type":"string"},"owner":{"maxLength":40,"type":"string"},"table_type":{"maxLength":40,"type":"string"},"updated_at":{"type":["integer","null"]},"view_definition":{"maxLength":1200,"type":["string","null"]}},"required":["full_name","table_type","data_source_format","owner","comment","created_at","updated_at","view_definition","columns","columns_omitted"],"type":"object"}},"required":["table"],"type":"object"}},{"id":"databricks.tables_list","title":"GET /unity-catalog/tables","summary":"List the tables and views inside one Unity Catalog schema, with each one's type and storage format. Columns are deliberately omitted here — fetch one table's full shape with databricks.table_get.","description":"List the tables and views inside one Unity Catalog schema, with each one's type and storage format. Columns are deliberately omitted here — fetch one table's full shape with databricks.table_get.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"catalog","type":"string","required":true,"description":"Catalog name.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"schema","type":"string","required":true,"description":"Schema name inside the catalog.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Tables per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Tables in analytics.gaming","args":{"catalog":"analytics","schema":"gaming"}}],"search_terms":["list tables in schema","find delta table"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"tables":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":40,"type":"string"},"data_source_format":{"maxLength":40,"type":["string","null"]},"name":{"maxLength":60,"type":"string"},"table_type":{"maxLength":40,"type":"string"},"updated_at":{"type":["integer","null"]}},"required":["name","table_type","data_source_format","comment","updated_at"],"type":"object"},"maxItems":10,"type":"array"}},"required":["tables","next_page_cursor"],"type":"object"}},{"id":"databricks.warehouse_get","title":"GET /sql/warehouses/<id>","summary":"Show one SQL warehouse's state, sizing, and health detail — including the failure summary when the platform reports it degraded. The state to poll after databricks.warehouse_start or databricks.warehouse_stop.","description":"Show one SQL warehouse's state, sizing, and health detail — including the failure summary when the platform reports it degraded. The state to poll after databricks.warehouse_start or databricks.warehouse_stop.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Health of the BI warehouse","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["warehouse health","why is warehouse degraded","warehouse state"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"auto_stop_mins":{"type":"integer"},"cluster_size":{"maxLength":24,"type":"string"},"creator":{"maxLength":60,"type":"string"},"health":{"additionalProperties":false,"properties":{"failure_code":{"maxLength":60,"type":["string","null"]},"status":{"maxLength":24,"type":"string"},"summary":{"maxLength":160,"type":["string","null"]}},"required":["status","summary","failure_code"],"type":["object","null"]},"id":{"maxLength":40,"type":"string"},"max_num_clusters":{"type":"integer"},"min_num_clusters":{"type":"integer"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"serverless":{"type":"boolean"},"state":{"maxLength":24,"type":"string"},"warehouse_type":{"maxLength":24,"type":"string"}},"required":["id","name","state","cluster_size","min_num_clusters","max_num_clusters","num_clusters","auto_stop_mins","serverless","warehouse_type","creator","health"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouse_start","title":"POST /sql/warehouses/<id>/start","summary":"Start a stopped SQL warehouse ahead of the queries that need it, so they skip the cold start. The API returns before the warehouse is up — the reported state is usually STARTING; poll databricks.warehouse_get until RUNNING. Starting a warehouse that is already running is a no-op.","description":"Start a stopped SQL warehouse ahead of the queries that need it, so they skip the cold start. The API returns before the warehouse is up — the reported state is usually STARTING; poll databricks.warehouse_get until RUNNING. Starting a warehouse that is already running is a no-op.","kind":"script","risk":"medium","side_effects":["Starts billable warehouse compute.","Asynchronous — returns before the warehouse reaches RUNNING."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Warm the BI warehouse before a batch of lookups","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["start sql warehouse","warm up warehouse"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["id","name","state","num_clusters"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouse_stop","title":"POST /sql/warehouses/<id>/stop","summary":"Stop a running SQL warehouse to cut its compute spend. Queries running on it are interrupted, and the next statement that arrives auto-starts it again at cold-start latency. The API returns before the warehouse is down — poll databricks.warehouse_get until STOPPED.","description":"Stop a running SQL warehouse to cut its compute spend. Queries running on it are interrupted, and the next statement that arrives auto-starts it again at cold-start latency. The API returns before the warehouse is down — poll databricks.warehouse_get until STOPPED.","kind":"script","risk":"medium","side_effects":["Interrupts queries currently running on the warehouse.","Stops billable compute; the next query pays the cold start.","Asynchronous — returns before the warehouse reaches STOPPED."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Stop an idle warehouse over the weekend","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["stop sql warehouse","cut warehouse cost"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["id","name","state","num_clusters"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouses_list","title":"GET /sql/warehouses","summary":"List the workspace's SQL warehouses with state, size, and health at a glance. The warehouse ID here is what databricks.sql_query runs on; a STOPPED warehouse auto-starts when a statement arrives, at cold-start latency.","description":"List the workspace's SQL warehouses with state, size, and health at a glance. The warehouse ID here is what databricks.sql_query runs on; a STOPPED warehouse auto-starts when a statement arrives, at cold-start latency.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":12,"description":"Warehouses per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"All warehouses and their states","args":{}}],"search_terms":["list sql warehouses","which warehouse is running"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"warehouses":{"items":{"additionalProperties":false,"properties":{"auto_stop_mins":{"type":"integer"},"cluster_size":{"maxLength":24,"type":"string"},"health_status":{"maxLength":24,"type":["string","null"]},"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"serverless":{"type":"boolean"},"state":{"maxLength":24,"type":"string"},"warehouse_type":{"maxLength":24,"type":"string"}},"required":["id","name","state","cluster_size","num_clusters","auto_stop_mins","serverless","warehouse_type","health_status"],"type":"object"},"maxItems":12,"type":"array"}},"required":["warehouses","next_page_cursor"],"type":"object"}},{"id":"databricks.whoami","title":"GET /preview/scim/v2/Me","summary":"Check which Databricks identity the runner's token authenticates as, and that the workspace is reachable at all. Use it first when any other action fails auth, or as the setup verification.","description":"Check which Databricks identity the runner's token authenticates as, and that the workspace is reachable at all. Use it first when any other action fails auth, or as the setup verification.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[],"examples":[{"title":"Verify the workspace connection","args":{}}],"search_terms":["check databricks token","which databricks user"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"active":{"type":"boolean"},"display_name":{"maxLength":80,"type":"string"},"id":{"maxLength":48,"type":"string"},"user_name":{"maxLength":100,"type":"string"}},"required":["id","user_name","display_name","active"],"type":"object"}}]},{"version":"0.1.0","content_hash":"sha256:1238a0fbdf048bf88b5dfe7693a427a7ca77a7b8c8210b354f081b44aa53235d","tarball_url":"https://registry.emisar.dev/v1/packs/databricks/0.1.0/1238a0fbdf048bf88b5dfe7693a427a7ca77a7b8c8210b354f081b44aa53235d/pack.tar.gz","actions":[{"id":"databricks.catalogs_list","title":"GET /unity-catalog/catalogs","summary":"List the Unity Catalog catalogs this token can see, with owner and type. The top of the catalog.schema.table hierarchy — start here when you need to find where a dataset lives.","description":"List the Unity Catalog catalogs this token can see, with owner and type. The top of the catalog.schema.table hierarchy — start here when you need to find where a dataset lives.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":10,"description":"Catalogs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"First page of catalogs","args":{}}],"search_terms":["list databricks catalogs","browse unity catalog"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"catalogs":{"items":{"additionalProperties":false,"properties":{"catalog_type":{"maxLength":40,"type":"string"},"comment":{"maxLength":40,"type":"string"},"created_at":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"owner":{"maxLength":40,"type":"string"}},"required":["name","catalog_type","owner","comment","created_at"],"type":"object"},"maxItems":10,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["catalogs","next_page_cursor"],"type":"object"}},{"id":"databricks.cluster_events","title":"POST /clusters/events","summary":"List one cluster's recent lifecycle events, newest first — starts, resizes, driver health, termination causes — the timeline for diagnosing why a cluster misbehaved. A read that the API happens to serve over POST.","description":"List one cluster's recent lifecycle events, newest first — starts, resizes, driver health, termination causes — the timeline for diagnosing why a cluster misbehaved. A read that the API happens to serve over POST.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the Databricks workspace API; changes nothing.","Read-only."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Events per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Timeline of a flapping cluster","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["cluster event log","cluster timeline","driver not responding"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"events":{"items":{"additionalProperties":false,"properties":{"current_workers":{"type":["integer","null"]},"reason_code":{"maxLength":60,"type":["string","null"]},"target_workers":{"type":["integer","null"]},"timestamp":{"type":["integer","null"]},"type":{"maxLength":48,"type":"string"},"user":{"maxLength":40,"type":["string","null"]}},"required":["timestamp","type","user","reason_code","current_workers","target_workers"],"type":"object"},"maxItems":12,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["events","next_page_cursor"],"type":"object"}},{"id":"databricks.cluster_get","title":"GET /clusters/get","summary":"Show one cluster's state in detail — including the termination reason when it is down, which is the first thing to read when a cluster died. Follow a suspicious termination with databricks.cluster_events for the timeline.","description":"Show one cluster's state in detail — including the termination reason when it is down, which is the first thing to read when a cluster died. Follow a suspicious termination with databricks.cluster_events for the timeline.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Why the shared cluster went down","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["why did the cluster terminate","cluster state detail"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"autoscale":{"additionalProperties":false,"properties":{"max_workers":{"type":"integer"},"min_workers":{"type":"integer"}},"required":["min_workers","max_workers"],"type":["object","null"]},"autotermination_minutes":{"type":["integer","null"]},"cluster_id":{"maxLength":60,"type":"string"},"creator":{"maxLength":40,"type":["string","null"]},"driver_node_type":{"maxLength":30,"type":["string","null"]},"name":{"maxLength":60,"type":"string"},"node_type":{"maxLength":30,"type":"string"},"num_workers":{"type":["integer","null"]},"source":{"maxLength":24,"type":"string"},"spark_version":{"maxLength":30,"type":"string"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"},"terminated_time":{"type":["integer","null"]},"termination_reason":{"additionalProperties":false,"properties":{"code":{"maxLength":60,"type":"string"},"type":{"maxLength":24,"type":["string","null"]}},"required":["code","type"],"type":["object","null"]}},"required":["cluster_id","name","state","state_message","spark_version","node_type","driver_node_type","num_workers","autoscale","autotermination_minutes","creator","source","start_time","terminated_time","termination_reason"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.cluster_restart","title":"POST /clusters/restart","summary":"Restart a running cluster — the fix for a wedged driver or a leaking Spark context. Everything attached dies with it: running notebooks lose their state and jobs executing on the cluster fail. The API returns before the restart completes; poll databricks.cluster_get until RUNNING again. A cluster that is not RUNNING is left untouched (the API treats that as a no-op).","description":"Restart a running cluster — the fix for a wedged driver or a leaking Spark context. Everything attached dies with it: running notebooks lose their state and jobs executing on the cluster fail. The API returns before the restart completes; poll databricks.cluster_get until RUNNING again. A cluster that is not RUNNING is left untouched (the API treats that as a no-op).","kind":"script","risk":"high","side_effects":["Kills every notebook session and job running on the cluster.","Asynchronous — returns before the cluster is back to RUNNING.","No-op when the cluster is not RUNNING."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Restart the cluster whose driver stopped responding","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["restart cluster","driver unresponsive fix"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"}},"required":["cluster_id","name","state","state_message"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.cluster_start","title":"POST /clusters/start","summary":"Start a terminated all-purpose cluster with its previous configuration. The API returns before the cluster is up — the reported state is usually PENDING; poll databricks.cluster_get until RUNNING. A cluster that is not TERMINATED is left untouched (the API treats that as a no-op), and job-launched clusters cannot be started.","description":"Start a terminated all-purpose cluster with its previous configuration. The API returns before the cluster is up — the reported state is usually PENDING; poll databricks.cluster_get until RUNNING. A cluster that is not TERMINATED is left untouched (the API treats that as a no-op), and job-launched clusters cannot be started.","kind":"script","risk":"medium","side_effects":["Starts billable cluster compute.","Asynchronous — returns before the cluster reaches RUNNING.","No-op when the cluster is not TERMINATED."],"args":[{"name":"cluster_id","type":"string","required":true,"description":"Cluster ID, from databricks.clusters_list.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Start the analytics cluster before working hours","args":{"cluster_id":"0811-104501-ab3cde45"}}],"search_terms":["start cluster","bring cluster back up"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cluster":{"additionalProperties":false,"properties":{"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"state":{"maxLength":24,"type":"string"},"state_message":{"maxLength":100,"type":"string"}},"required":["cluster_id","name","state","state_message"],"type":"object"}},"required":["cluster"],"type":"object"}},{"id":"databricks.clusters_list","title":"GET /clusters/list","summary":"List the workspace's all-purpose and job clusters with state, Spark version, and sizing. Filter by state to see only what is RUNNING — or what died in ERROR.","description":"List the workspace's all-purpose and job clusters with state, Spark version, and sizing. Filter by state to see only what is RUNNING — or what died in ERROR.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"state","type":"string","required":false,"default":"","description":"Only clusters in this state; empty means all.","validation":{"pattern":"^(|PENDING|RUNNING|RESTARTING|RESIZING|TERMINATING|TERMINATED|ERROR|UNKNOWN)$","max_length":24}},{"name":"page_size","type":"integer","required":false,"default":8,"description":"Clusters per page.","validation":{"min":1,"max":8}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Only what is currently running","args":{"state":"RUNNING"}}],"search_terms":["list databricks clusters","running clusters"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"clusters":{"items":{"additionalProperties":false,"properties":{"autoscale":{"additionalProperties":false,"properties":{"max_workers":{"type":"integer"},"min_workers":{"type":"integer"}},"required":["min_workers","max_workers"],"type":["object","null"]},"cluster_id":{"maxLength":60,"type":"string"},"name":{"maxLength":60,"type":"string"},"node_type":{"maxLength":24,"type":"string"},"num_workers":{"type":["integer","null"]},"source":{"maxLength":24,"type":"string"},"spark_version":{"maxLength":24,"type":"string"},"state":{"maxLength":24,"type":"string"}},"required":["cluster_id","name","state","spark_version","node_type","num_workers","autoscale","source"],"type":"object"},"maxItems":8,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["clusters","next_page_cursor"],"type":"object"}},{"id":"databricks.dashboard_get","title":"GET /lakeview/dashboards/<id>","summary":"Show what one AI/BI (Lakeview) dashboard is made of: its pages, and each dataset behind it with the dataset's parameter keywords. The dataset names here are what databricks.dashboard_sql takes to fetch the actual SQL, and the warehouse_id is where that SQL runs.","description":"Show what one AI/BI (Lakeview) dashboard is made of: its pages, and each dataset behind it with the dataset's parameter keywords. The dataset names here are what databricks.dashboard_sql takes to fetch the actual SQL, and the warehouse_id is where that SQL runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"dashboard_id","type":"string","required":true,"description":"Dashboard ID, from databricks.dashboards_list or the dashboard's /dashboardsv3/<id> URL.","validation":{"pattern":"^[A-Za-z0-9-]{16,40}$","max_length":40}}],"examples":[{"title":"Datasets behind a dashboard from its URL","args":{"dashboard_id":"01f0138fd0d11a23822c3f6384e6c484"}}],"search_terms":["what feeds this dashboard","dashboard datasets","dashboard pages"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboard":{"additionalProperties":false,"properties":{"create_time":{"maxLength":40,"type":"string"},"dashboard_id":{"maxLength":40,"type":"string"},"datasets":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"},"parameter_keywords":{"items":{"maxLength":24,"type":"string"},"maxItems":4,"type":"array"}},"required":["name","display_name","parameter_keywords"],"type":"object"},"maxItems":10,"type":"array"},"datasets_omitted":{"type":"integer"},"display_name":{"maxLength":60,"type":"string"},"lifecycle_state":{"maxLength":24,"type":"string"},"pages":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"}},"required":["name","display_name"],"type":"object"},"maxItems":6,"type":"array"},"pages_omitted":{"type":"integer"},"path":{"maxLength":80,"type":["string","null"]},"update_time":{"maxLength":40,"type":"string"},"warehouse_id":{"maxLength":40,"type":["string","null"]}},"required":["dashboard_id","display_name","lifecycle_state","create_time","update_time","warehouse_id","path","datasets","datasets_omitted","pages","pages_omitted"],"type":"object"}},"required":["dashboard"],"type":"object"}},{"id":"databricks.dashboard_sql","title":"GET /lakeview/dashboards/<id> dataset SQL","summary":"Show the SQL behind one dataset of an AI/BI (Lakeview) dashboard, with the dataset's parameters. The query may contain :parameter markers — replace each with a literal value before re-running it through databricks.sql_query on the dashboard's warehouse. Get dataset names from databricks.dashboard_get; the name and the display name both match.","description":"Show the SQL behind one dataset of an AI/BI (Lakeview) dashboard, with the dataset's parameters. The query may contain :parameter markers — replace each with a literal value before re-running it through databricks.sql_query on the dashboard's warehouse. Get dataset names from databricks.dashboard_get; the name and the display name both match.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"dashboard_id","type":"string","required":true,"description":"Dashboard ID, from databricks.dashboards_list or the dashboard's /dashboardsv3/<id> URL.","validation":{"pattern":"^[A-Za-z0-9-]{16,40}$","max_length":40}},{"name":"dataset","type":"string","required":true,"description":"Dataset name or display name, from databricks.dashboard_get.","validation":{"max_length":120}}],"examples":[{"title":"The SQL feeding a dashboard's main dataset","args":{"dashboard_id":"01f0138fd0d11a23822c3f6384e6c484","dataset":"Daily matches"}}],"search_terms":["sql behind dashboard","dashboard query text","dataset query"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboard_id":{"maxLength":40,"type":"string"},"dataset":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"name":{"maxLength":24,"type":"string"}},"required":["name","display_name"],"type":"object"},"parameters":{"items":{"additionalProperties":false,"properties":{"display_name":{"maxLength":40,"type":"string"},"keyword":{"maxLength":24,"type":"string"}},"required":["keyword","display_name"],"type":"object"},"maxItems":6,"type":"array"},"sql":{"maxLength":2800,"type":"string"},"sql_bytes_total":{"type":"integer"},"sql_truncated":{"type":"boolean"}},"required":["dashboard_id","dataset","sql","sql_bytes_total","sql_truncated","parameters"],"type":"object"}},{"id":"databricks.dashboards_list","title":"GET /lakeview/dashboards","summary":"List the workspace's AI/BI (Lakeview) dashboards with their lifecycle state and default warehouse. Use it to find the dashboard ID that databricks.dashboard_get and databricks.dashboard_sql take — the same ID that appears in a dashboard's /dashboardsv3/<id> URL.","description":"List the workspace's AI/BI (Lakeview) dashboards with their lifecycle state and default warehouse. Use it to find the dashboard ID that databricks.dashboard_get and databricks.dashboard_sql take — the same ID that appears in a dashboard's /dashboardsv3/<id> URL.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":12,"description":"Dashboards per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"First page of dashboards","args":{}}],"search_terms":["list databricks dashboards","find dashboard id"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"dashboards":{"items":{"additionalProperties":false,"properties":{"create_time":{"maxLength":40,"type":"string"},"dashboard_id":{"maxLength":40,"type":"string"},"display_name":{"maxLength":60,"type":"string"},"lifecycle_state":{"maxLength":24,"type":"string"},"warehouse_id":{"maxLength":40,"type":["string","null"]}},"required":["dashboard_id","display_name","lifecycle_state","create_time","warehouse_id"],"type":"object"},"maxItems":12,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["dashboards","next_page_cursor"],"type":"object"}},{"id":"databricks.job_get","title":"GET /jobs/get","summary":"Show one job's definition: its schedule, task graph with each task's kind and dependencies, and the job-level parameters with their defaults — what you review before triggering databricks.job_run_now.","description":"Show one job's definition: its schedule, task graph with each task's kind and dependencies, and the job-level parameters with their defaults — what you review before triggering databricks.job_run_now.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job ID, from databricks.jobs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Review the nightly ETL job before running it","args":{"job_id":947381205673284}}],"search_terms":["job schedule and tasks","show workflow definition","job parameters"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"job":{"additionalProperties":false,"properties":{"creator":{"maxLength":60,"type":["string","null"]},"job_id":{"type":"integer"},"max_concurrent_runs":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"parameters":{"items":{"additionalProperties":false,"properties":{"default":{"maxLength":40,"type":"string"},"name":{"maxLength":30,"type":"string"}},"required":["name","default"],"type":"object"},"maxItems":8,"type":"array"},"run_as":{"maxLength":60,"type":["string","null"]},"schedule":{"additionalProperties":false,"properties":{"cron":{"maxLength":60,"type":"string"},"paused":{"type":"boolean"},"timezone":{"maxLength":30,"type":"string"}},"required":["cron","timezone","paused"],"type":["object","null"]},"tasks":{"items":{"additionalProperties":false,"properties":{"depends_on":{"items":{"maxLength":40,"type":"string"},"maxItems":2,"type":"array"},"kind":{"maxLength":24,"type":"string"},"task_key":{"maxLength":40,"type":"string"}},"required":["task_key","kind","depends_on"],"type":"object"},"maxItems":12,"type":"array"},"tasks_omitted":{"type":"integer"}},"required":["job_id","name","creator","run_as","max_concurrent_runs","schedule","parameters","tasks","tasks_omitted"],"type":"object"}},"required":["job"],"type":"object"}},{"id":"databricks.job_run_cancel","title":"POST /jobs/runs/cancel","summary":"Cancel a running job run — or a single task run — and report the state it reached. Cancellation is asynchronous: the reported state is often still TERMINATING; poll databricks.job_run_get until it settles. The job itself stays defined and can be run again.","description":"Cancel a running job run — or a single task run — and report the state it reached. Cancellation is asynchronous: the reported state is often still TERMINATING; poll databricks.job_run_get until it settles. The job itself stays defined and can be run again.","kind":"script","risk":"medium","side_effects":["Interrupts the run's tasks; a task stopped mid-write leaves whatever its own code leaves.","Asynchronous — the run may still be terminating when this returns."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Run ID, from databricks.job_runs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Stop a run stuck on a dead cluster","args":{"run_id":738495610284753}}],"search_terms":["cancel job run","stop stuck workflow"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","state","result"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"databricks.job_run_get","title":"GET /jobs/runs/get","summary":"Show one job run's state and its per-task breakdown — which task failed, each task's own run_id, and how long each took. A failed task's run_id is what databricks.job_run_output takes for the error detail.","description":"Show one job run's state and its per-task breakdown — which task failed, each task's own run_id, and how long each took. A failed task's run_id is what databricks.job_run_output takes for the error detail.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Job run ID, from databricks.job_runs_list.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Break a failed run down by task","args":{"run_id":738495610284753}}],"search_terms":["which task failed","job run status","task run ids"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"end_time":{"type":["integer","null"]},"job_id":{"type":"integer"},"message":{"maxLength":100,"type":"string"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"run_name":{"maxLength":60,"type":"string"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"tasks":{"items":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"},"task_key":{"maxLength":40,"type":"string"}},"required":["task_key","run_id","state","result","duration_ms"],"type":"object"},"maxItems":10,"type":"array"},"tasks_omitted":{"type":"integer"}},"required":["run_id","job_id","run_name","state","result","message","start_time","end_time","duration_ms","tasks","tasks_omitted"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"databricks.job_run_now","title":"POST /jobs/run-now","summary":"Trigger a run of an existing job now, optionally overriding its job-level parameters. This executes whatever the job's tasks are defined to do — including writes to production tables — so review the definition with databricks.job_get first. Returns the new run's ID and state; follow it with databricks.job_run_get.","description":"Trigger a run of an existing job now, optionally overriding its job-level parameters. This executes whatever the job's tasks are defined to do — including writes to production tables — so review the definition with databricks.job_get first. Returns the new run's ID and state; follow it with databricks.job_run_get.","kind":"script","risk":"high","side_effects":["Executes the job's workload — may read and write production data.","Starts or consumes job compute, which is billed.","The run continues after this action returns."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job ID, from databricks.jobs_list.","validation":{"min":1,"max":9007199254740991}},{"name":"job_params","type":"string_array","required":false,"default":[],"description":"Job-level parameter overrides as name=value pairs, for parameters the job declares (see databricks.job_get).","validation":{"max_items":32,"max_length":512}},{"name":"idempotency_key","type":"string","required":false,"default":"","description":"Token guaranteeing exactly one launched run — a retry with the same token returns the existing run instead of launching another.","validation":{"max_length":64}}],"examples":[{"title":"Re-run the nightly ETL for one date","args":{"idempotency_key":"emisar-backfill-2026-08-10","job_id":947381205673284,"job_params":["run_date=2026-08-10"]}}],"search_terms":["trigger job run","run workflow now","rerun the etl"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"job_id":{"type":"integer"},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","job_id","state"],"type":"object"}},{"id":"databricks.job_run_output","title":"GET /jobs/runs/get-output","summary":"Show why one task run failed: the error, a bounded tail of its error trace and logs, and the notebook's exit value if it set one. Takes a TASK run's ID — get it from the tasks list in databricks.job_run_get, not the job run's own ID.","description":"Show why one task run failed: the error, a bounded tail of its error trace and logs, and the notebook's exit value if it set one. Takes a TASK run's ID — get it from the tasks list in databricks.job_run_get, not the job run's own ID.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Log and error content is arbitrary task output, returned to the model."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Task run ID, from the tasks list of databricks.job_run_get.","validation":{"min":1,"max":9007199254740991}}],"examples":[{"title":"Error detail for the failed ingest task","args":{"run_id":738495610284754}}],"search_terms":["why did the task fail","job run error trace","notebook output"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"error":{"maxLength":150,"type":["string","null"]},"error_trace_tail":{"items":{"maxLength":80,"type":"string"},"maxItems":10,"type":"array"},"logs_tail":{"items":{"maxLength":80,"type":"string"},"maxItems":6,"type":"array"},"logs_truncated":{"type":"boolean"},"notebook_result":{"maxLength":200,"type":["string","null"]},"notebook_result_truncated":{"type":"boolean"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["run_id","state","result","error","error_trace_tail","logs_tail","logs_truncated","notebook_result","notebook_result_truncated"],"type":"object"}},{"id":"databricks.job_runs_list","title":"GET /jobs/runs/list","summary":"List recent job runs, newest first — the workspace-wide \"what ran and what failed\" view. Filter to one job with job_id, or to only active or only completed runs. Each run's result code says why it ended; dig into one run with databricks.job_run_get.","description":"List recent job runs, newest first — the workspace-wide \"what ran and what failed\" view. Filter to one job with job_id, or to only active or only completed runs. Each run's result code says why it ended; dig into one run with databricks.job_run_get.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"job_id","type":"integer","required":false,"default":0,"description":"Only this job's runs; 0 means runs from all jobs.","validation":{"min":0,"max":9007199254740991}},{"name":"active_only","type":"boolean","required":false,"default":false,"description":"Only queued, pending, or running runs."},{"name":"completed_only","type":"boolean","required":false,"default":false,"description":"Only finished runs."},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Runs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"What failed recently, workspace-wide","args":{"completed_only":true}},{"title":"Runs of one job","args":{"job_id":947381205673284}}],"search_terms":["recent job runs","failed job runs","is the job still running"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"duration_ms":{"type":["integer","null"]},"job_id":{"type":"integer"},"message":{"maxLength":60,"type":"string"},"result":{"maxLength":40,"type":["string","null"]},"run_id":{"type":"integer"},"start_time":{"type":["integer","null"]},"state":{"maxLength":24,"type":"string"}},"required":["run_id","job_id","state","result","message","start_time","duration_ms"],"type":"object"},"maxItems":10,"type":"array"}},"required":["runs","next_page_cursor"],"type":"object"}},{"id":"databricks.jobs_list","title":"GET /jobs/list","summary":"List the workspace's jobs (workflows) with their creator. Use the name filter to find one job by its exact, case-insensitive name; the job_id here is what the run actions take.","description":"List the workspace's jobs (workflows) with their creator. Use the name filter to find one job by its exact, case-insensitive name; the job_id here is what the run actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"name","type":"string","required":false,"default":"","description":"Filter on the exact (case-insensitive) job name.","validation":{"max_length":100}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Jobs per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Find the nightly ETL job","args":{"name":"nightly-etl"}}],"search_terms":["list databricks jobs","find workflow by name"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"jobs":{"items":{"additionalProperties":false,"properties":{"created_time":{"type":["integer","null"]},"creator":{"maxLength":60,"type":"string"},"job_id":{"type":"integer"},"name":{"maxLength":60,"type":"string"}},"required":["job_id","name","creator","created_time"],"type":"object"},"maxItems":10,"type":"array"},"next_page_cursor":{"maxLength":2048,"type":["string","null"]}},"required":["jobs","next_page_cursor"],"type":"object"}},{"id":"databricks.schemas_list","title":"GET /unity-catalog/schemas","summary":"List the schemas inside one Unity Catalog catalog. The middle level of the catalog.schema.table hierarchy, between databricks.catalogs_list and databricks.tables_list.","description":"List the schemas inside one Unity Catalog catalog. The middle level of the catalog.schema.table hierarchy, between databricks.catalogs_list and databricks.tables_list.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"catalog","type":"string","required":true,"description":"Catalog name, from databricks.catalogs_list.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Schemas per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Schemas in the analytics catalog","args":{"catalog":"analytics"}}],"search_terms":["list schemas in catalog","databricks databases"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"schemas":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":40,"type":"string"},"created_at":{"type":["integer","null"]},"name":{"maxLength":60,"type":"string"},"owner":{"maxLength":40,"type":"string"}},"required":["name","owner","comment","created_at"],"type":"object"},"maxItems":10,"type":"array"}},"required":["schemas","next_page_cursor"],"type":"object"}},{"id":"databricks.sql_query","title":"POST /sql/statements","summary":"Run one read-only SQL statement on a Databricks SQL warehouse and return a bounded slice of the result: column names and types, rows as strings, and honest counts of everything clipped away.","description":"Run one read-only SQL statement on a Databricks SQL warehouse and return a bounded slice of the result: column names and types, rows as strings, and honest counts of everything clipped away. The statement must start with SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN — put a CTE inside a subquery (SELECT ... FROM (WITH ... SELECT ...) q) — and runs with exactly the grants the runner's token holds. If the warehouse is still starting when the wait elapses, the statement keeps running and the returned state is PENDING or RUNNING: poll it with databricks.sql_statement.","kind":"script","risk":"medium","side_effects":["Executes the statement on the warehouse — consumes warehouse compute.","Starts the warehouse if it is auto-stopped.","Result content is arbitrary table data, returned to the model."],"args":[{"name":"sql","type":"string","required":true,"description":"A single read statement (SELECT, VALUES, SHOW, DESCRIBE, or EXPLAIN). Use catalog.schema.table names, or set the catalog/schema args.","validation":{"max_length":8192}},{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}},{"name":"catalog","type":"string","required":false,"default":"","description":"Default catalog for unqualified names, like USE CATALOG.","validation":{"pattern":"^[A-Za-z0-9_]*$","max_length":255}},{"name":"schema","type":"string","required":false,"default":"","description":"Default schema for unqualified names, like USE SCHEMA.","validation":{"pattern":"^[A-Za-z0-9_]*$","max_length":255}},{"name":"wait_seconds","type":"integer","required":false,"default":30,"description":"How long the API call waits for the statement to finish.","validation":{"min":5,"max":50}},{"name":"row_limit","type":"integer","required":false,"default":100,"description":"Rows the statement may return before the API truncates it.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Look up yesterday's active users","args":{"sql":"SELECT event_date, count(DISTINCT user_id) AS dau FROM analytics.product.events WHERE event_date >= current_date() - 1 GROUP BY 1 ORDER BY 1","warehouse_id":"1234567890abcdef"}},{"title":"Re-run a dashboard dataset's SQL in its own catalog and schema","args":{"catalog":"analytics","row_limit":50,"schema":"gaming","sql":"SELECT game, count(*) AS matches FROM matches_daily GROUP BY 1 ORDER BY 2 DESC","warehouse_id":"1234567890abcdef"}}],"search_terms":["query databricks table","run sql on warehouse","select from delta table"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"api_truncated":{"type":"boolean"},"columns":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":40,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["name","type"],"type":"object"},"maxItems":16,"type":"array"},"columns_omitted":{"type":"integer"},"rows":{"items":{"items":{"maxLength":60,"type":["string","null"]},"maxItems":16,"type":"array"},"maxItems":1000,"type":"array"},"rows_omitted":{"type":"integer"},"state":{"enum":["PENDING","RUNNING","SUCCEEDED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"},"total_rows":{"type":["integer","null"]}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.sql_statement","title":"GET /sql/statements/<id>","summary":"Check a submitted SQL statement's state and fetch its result once it finished — the poll half of databricks.sql_query for statements that outlived the request's wait. Returns the same bounded result shape.","description":"Check a submitted SQL statement's state and fetch its result once it finished — the poll half of databricks.sql_query for statements that outlived the request's wait. Returns the same bounded result shape.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Result content is arbitrary table data, returned to the model."],"args":[{"name":"statement_id","type":"string","required":true,"description":"Statement ID returned by databricks.sql_query.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Poll a statement that was still running","args":{"statement_id":"01f01390-a2b3-1c4d-9e8f-7a6b5c4d3e2f"}}],"search_terms":["poll sql statement","fetch query result"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"api_truncated":{"type":"boolean"},"columns":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":40,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["name","type"],"type":"object"},"maxItems":16,"type":"array"},"columns_omitted":{"type":"integer"},"rows":{"items":{"items":{"maxLength":60,"type":["string","null"]},"maxItems":16,"type":"array"},"maxItems":1000,"type":"array"},"rows_omitted":{"type":"integer"},"state":{"enum":["PENDING","RUNNING","SUCCEEDED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"},"total_rows":{"type":["integer","null"]}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.sql_statement_cancel","title":"POST /sql/statements/<id>/cancel","summary":"Cancel a running SQL statement so it stops consuming the warehouse, then report the state the statement actually reached. Cancellation is best-effort: a statement that finished first reports its terminal state instead.","description":"Cancel a running SQL statement so it stops consuming the warehouse, then report the state the statement actually reached. Cancellation is best-effort: a statement that finished first reports its terminal state instead.","kind":"script","risk":"medium","side_effects":["Stops the statement's execution on the warehouse.","A statement that already finished is left as it ended."],"args":[{"name":"statement_id","type":"string","required":true,"description":"Statement ID returned by databricks.sql_query.","validation":{"pattern":"^[A-Za-z0-9-]{8,64}$","max_length":64}}],"examples":[{"title":"Cancel a statement stuck on a cold warehouse","args":{"statement_id":"01f01390-a2b3-1c4d-9e8f-7a6b5c4d3e2f"}}],"search_terms":["cancel sql statement","stop runaway query"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"state":{"enum":["PENDING","RUNNING","SUCCEEDED","FAILED","CANCELED","CLOSED"],"type":"string"},"statement_id":{"maxLength":64,"type":"string"}},"required":["statement_id","state"],"type":"object"}},{"id":"databricks.table_get","title":"GET /unity-catalog/tables/<full_name>","summary":"Show one Unity Catalog table's shape: columns with their SQL types and nullability, the table type and storage format, and — for a view — the defining SQL. What you read before writing a databricks.sql_query against an unfamiliar table.","description":"Show one Unity Catalog table's shape: columns with their SQL types and nullability, the table type and storage format, and — for a view — the defining SQL. What you read before writing a databricks.sql_query against an unfamiliar table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"full_name","type":"string","required":true,"description":"Three-level name, catalog.schema.table.","validation":{"pattern":"^[A-Za-z0-9_]{1,100}\\.[A-Za-z0-9_]{1,100}\\.[A-Za-z0-9_]{1,100}$","max_length":255}}],"examples":[{"title":"Shape of the matches table","args":{"full_name":"analytics.gaming.matches_daily"}}],"search_terms":["table columns and types","describe databricks table","view definition sql"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"table":{"additionalProperties":false,"properties":{"columns":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":24,"type":["string","null"]},"name":{"maxLength":40,"type":"string"},"nullable":{"type":"boolean"},"type":{"maxLength":40,"type":"string"}},"required":["name","type","nullable","comment"],"type":"object"},"maxItems":12,"type":"array"},"columns_omitted":{"type":"integer"},"comment":{"maxLength":60,"type":"string"},"created_at":{"type":["integer","null"]},"data_source_format":{"maxLength":40,"type":["string","null"]},"full_name":{"maxLength":255,"type":"string"},"owner":{"maxLength":40,"type":"string"},"table_type":{"maxLength":40,"type":"string"},"updated_at":{"type":["integer","null"]},"view_definition":{"maxLength":1200,"type":["string","null"]}},"required":["full_name","table_type","data_source_format","owner","comment","created_at","updated_at","view_definition","columns","columns_omitted"],"type":"object"}},"required":["table"],"type":"object"}},{"id":"databricks.tables_list","title":"GET /unity-catalog/tables","summary":"List the tables and views inside one Unity Catalog schema, with each one's type and storage format. Columns are deliberately omitted here — fetch one table's full shape with databricks.table_get.","description":"List the tables and views inside one Unity Catalog schema, with each one's type and storage format. Columns are deliberately omitted here — fetch one table's full shape with databricks.table_get.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"catalog","type":"string","required":true,"description":"Catalog name.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"schema","type":"string","required":true,"description":"Schema name inside the catalog.","validation":{"pattern":"^[A-Za-z0-9_]{1,255}$","max_length":255}},{"name":"page_size","type":"integer","required":false,"default":10,"description":"Tables per page.","validation":{"min":1,"max":10}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"Tables in analytics.gaming","args":{"catalog":"analytics","schema":"gaming"}}],"search_terms":["list tables in schema","find delta table"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"tables":{"items":{"additionalProperties":false,"properties":{"comment":{"maxLength":40,"type":"string"},"data_source_format":{"maxLength":40,"type":["string","null"]},"name":{"maxLength":60,"type":"string"},"table_type":{"maxLength":40,"type":"string"},"updated_at":{"type":["integer","null"]}},"required":["name","table_type","data_source_format","comment","updated_at"],"type":"object"},"maxItems":10,"type":"array"}},"required":["tables","next_page_cursor"],"type":"object"}},{"id":"databricks.warehouse_get","title":"GET /sql/warehouses/<id>","summary":"Show one SQL warehouse's state, sizing, and health detail — including the failure summary when the platform reports it degraded. The state to poll after databricks.warehouse_start or databricks.warehouse_stop.","description":"Show one SQL warehouse's state, sizing, and health detail — including the failure summary when the platform reports it degraded. The state to poll after databricks.warehouse_start or databricks.warehouse_stop.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Health of the BI warehouse","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["warehouse health","why is warehouse degraded","warehouse state"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"auto_stop_mins":{"type":"integer"},"cluster_size":{"maxLength":24,"type":"string"},"creator":{"maxLength":60,"type":"string"},"health":{"additionalProperties":false,"properties":{"failure_code":{"maxLength":60,"type":["string","null"]},"status":{"maxLength":24,"type":"string"},"summary":{"maxLength":160,"type":["string","null"]}},"required":["status","summary","failure_code"],"type":["object","null"]},"id":{"maxLength":40,"type":"string"},"max_num_clusters":{"type":"integer"},"min_num_clusters":{"type":"integer"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"serverless":{"type":"boolean"},"state":{"maxLength":24,"type":"string"},"warehouse_type":{"maxLength":24,"type":"string"}},"required":["id","name","state","cluster_size","min_num_clusters","max_num_clusters","num_clusters","auto_stop_mins","serverless","warehouse_type","creator","health"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouse_start","title":"POST /sql/warehouses/<id>/start","summary":"Start a stopped SQL warehouse ahead of the queries that need it, so they skip the cold start. The API returns before the warehouse is up — the reported state is usually STARTING; poll databricks.warehouse_get until RUNNING. Starting a warehouse that is already running is a no-op.","description":"Start a stopped SQL warehouse ahead of the queries that need it, so they skip the cold start. The API returns before the warehouse is up — the reported state is usually STARTING; poll databricks.warehouse_get until RUNNING. Starting a warehouse that is already running is a no-op.","kind":"script","risk":"medium","side_effects":["Starts billable warehouse compute.","Asynchronous — returns before the warehouse reaches RUNNING."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Warm the BI warehouse before a batch of lookups","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["start sql warehouse","warm up warehouse"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["id","name","state","num_clusters"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouse_stop","title":"POST /sql/warehouses/<id>/stop","summary":"Stop a running SQL warehouse to cut its compute spend. Queries running on it are interrupted, and the next statement that arrives auto-starts it again at cold-start latency. The API returns before the warehouse is down — poll databricks.warehouse_get until STOPPED.","description":"Stop a running SQL warehouse to cut its compute spend. Queries running on it are interrupted, and the next statement that arrives auto-starts it again at cold-start latency. The API returns before the warehouse is down — poll databricks.warehouse_get until STOPPED.","kind":"script","risk":"medium","side_effects":["Interrupts queries currently running on the warehouse.","Stops billable compute; the next query pays the cold start.","Asynchronous — returns before the warehouse reaches STOPPED."],"args":[{"name":"warehouse_id","type":"string","required":true,"description":"SQL warehouse ID, from databricks.warehouses_list.","validation":{"pattern":"^[A-Za-z0-9]{8,40}$","max_length":40}}],"examples":[{"title":"Stop an idle warehouse over the weekend","args":{"warehouse_id":"1234567890abcdef"}}],"search_terms":["stop sql warehouse","cut warehouse cost"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"warehouse":{"additionalProperties":false,"properties":{"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"state":{"maxLength":24,"type":"string"}},"required":["id","name","state","num_clusters"],"type":"object"}},"required":["warehouse"],"type":"object"}},{"id":"databricks.warehouses_list","title":"GET /sql/warehouses","summary":"List the workspace's SQL warehouses with state, size, and health at a glance. The warehouse ID here is what databricks.sql_query runs on; a STOPPED warehouse auto-starts when a statement arrives, at cold-start latency.","description":"List the workspace's SQL warehouses with state, size, and health at a glance. The warehouse ID here is what databricks.sql_query runs on; a STOPPED warehouse auto-starts when a statement arrives, at cold-start latency.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":12,"description":"Warehouses per page.","validation":{"min":1,"max":12}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation token from the previous page.","validation":{"max_length":2048}}],"examples":[{"title":"All warehouses and their states","args":{}}],"search_terms":["list sql warehouses","which warehouse is running"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page_cursor":{"maxLength":2048,"type":["string","null"]},"warehouses":{"items":{"additionalProperties":false,"properties":{"auto_stop_mins":{"type":"integer"},"cluster_size":{"maxLength":24,"type":"string"},"health_status":{"maxLength":24,"type":["string","null"]},"id":{"maxLength":40,"type":"string"},"name":{"maxLength":60,"type":"string"},"num_clusters":{"type":"integer"},"serverless":{"type":"boolean"},"state":{"maxLength":24,"type":"string"},"warehouse_type":{"maxLength":24,"type":"string"}},"required":["id","name","state","cluster_size","num_clusters","auto_stop_mins","serverless","warehouse_type","health_status"],"type":"object"},"maxItems":12,"type":"array"}},"required":["warehouses","next_page_cursor"],"type":"object"}},{"id":"databricks.whoami","title":"GET /preview/scim/v2/Me","summary":"Check which Databricks identity the runner's token authenticates as, and that the workspace is reachable at all. Use it first when any other action fails auth, or as the setup verification.","description":"Check which Databricks identity the runner's token authenticates as, and that the workspace is reachable at all. Use it first when any other action fails auth, or as the setup verification.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Databricks workspace API.","Read-only."],"args":[],"examples":[{"title":"Verify the workspace connection","args":{}}],"search_terms":["check databricks token","which databricks user"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"active":{"type":"boolean"},"display_name":{"maxLength":80,"type":"string"},"id":{"maxLength":48,"type":"string"},"user_name":{"maxLength":100,"type":"string"}},"required":["id","user_name","display_name","active"],"type":"object"}}]}]},{"id":"debian","name":"Debian/Ubuntu package operations","version":"0.1.12","description":"Operator pack for Debian/Ubuntu hosts. Read-only inventory and patching diagnostics, plus narrow apt install/remove actions for a single named package. Designed for production hosts where a human approver must see the package name before a write happens.","vendor":"emisar","homepage":"https://emisar.dev/packs/debian","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/debian","content_hash":"sha256:360787d1ea92d4e6f294877c23d8d50f93ada4625f17ce0310179157eafd9b1b","tarball_url":"https://registry.emisar.dev/v1/packs/debian/0.1.12/360787d1ea92d4e6f294877c23d8d50f93ada4625f17ce0310179157eafd9b1b/pack.tar.gz","requires":{"os":["linux"],"binaries":["apt-get","dpkg"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","notes":["Read-only inventory (dpkg_status, apt_upgradable, apt_security_check, kernel_info) needs no privilege."],"host_access":[{"actions":["debian.apt_update","debian.apt_install","debian.apt_remove","debian.apt_autoremove"],"requirement":"Update apt state and install or remove packages as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-debian-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Package actions can run maintainer scripts and change any file or service those packages control."}]}],"verify":"debian.dpkg_status"},"actions":[{"id":"debian.apt_autoremove","title":"apt autoremove","summary":"Drop packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","description":"Drop packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes possibly many packages, including old kernels.","Triggers prerm/postrm scripts."],"args":[],"examples":[{"title":"Clean up orphaned deps","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["autoremove","-y"]}},{"id":"debian.apt_install","title":"apt install (one package)","summary":"Install ONE named package non-interactively. Its maintainer scripts run as root and typically start or restart the service it ships. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","description":"Install ONE named package non-interactively. Its maintainer scripts run as root and typically start or restart the service it ships. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Downloads from configured sources.","Modifies /var/lib/dpkg.","Triggers postinst scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Install fail2ban","args":{"package":"fail2ban"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["install","-y","--no-install-recommends","{{ args.package }}"]}},{"id":"debian.apt_remove","title":"apt remove (one package)","summary":"Remove ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","description":"Remove ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes binaries from /usr.","Triggers prerm/postrm scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Remove obsolete ftp client","args":{"package":"ftp"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["remove","-y","{{ args.package }}"]}},{"id":"debian.apt_security_check","title":"Pending security upgrades","summary":"List upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","description":"List upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"Are there security patches pending?","args":{}}],"search_terms":["vulnerabilities","cve","unpatched"],"command":{"binary":"/bin/sh","argv":["-c","upgradable=$(apt list --upgradable 2>/dev/null) || { echo \"apt list --upgradable failed\" >&2; exit 1; }\nprintf '%s\\n' \"$upgradable\" | grep -E '\\-security|security\\.(debian|ubuntu)' || echo 'no pending security upgrades'\n"]}},{"id":"debian.apt_update","title":"apt-get update","summary":"Refresh the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","description":"Refresh the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","kind":"exec","risk":"medium","side_effects":["Writes /var/lib/apt/lists/*.","Holds the apt lock briefly.","Outgoing HTTPS to configured sources."],"args":[],"examples":[{"title":"Refresh apt index","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["update","-qq"]}},{"id":"debian.apt_upgradable","title":"List upgradable packages","summary":"List packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","description":"List packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"What needs upgrading?","args":{}}],"search_terms":["pending updates","outdated packages"],"command":{"binary":"apt","argv":["list","--upgradable"]}},{"id":"debian.dpkg_changes","title":"Recent dpkg installs/removes","summary":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","description":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/dpkg.log and its rotated logs (/var/log/dpkg.log.1, /var/log/dpkg.log.*.gz)."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 dpkg log lines","args":{}}],"search_terms":["what changed recently","recent installs","package history"],"command":{"binary":"/bin/sh","argv":["-c","[ -r /var/log/dpkg.log ] || { echo \"no readable dpkg log at /var/log/dpkg.log\" >&2; exit 1; }\nzcat -f /var/log/dpkg.log /var/log/dpkg.log.* 2>/dev/null | sort | tail -n {{ args.lines }}\n"]}},{"id":"debian.dpkg_status","title":"dpkg package status","summary":"Return the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","description":"Return the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/dpkg/status."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Is openssl installed and what version?","args":{"package":"openssl"}}],"search_terms":[],"command":{"binary":"dpkg","argv":["-s","{{ args.package }}"]}},{"id":"debian.kernel_info","title":"Kernel + uptime + reboot-required","summary":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","description":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","kind":"exec","risk":"low","side_effects":["One uname call, one uptime call, stat on /var/run/reboot-required."],"args":[],"examples":[{"title":"Kernel + reboot posture","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","uname -a; uptime; if [ -f /var/run/reboot-required ]; then echo 'reboot-required: yes'; cat /var/run/reboot-required.pkgs 2>/dev/null || true; else echo 'reboot-required: no'; fi"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:5ae06f3fd4fd7198e96ab831c6747a201aac35cc450a07444a30d403957bb549","tarball_url":"https://registry.emisar.dev/v1/packs/debian/0.1.10/5ae06f3fd4fd7198e96ab831c6747a201aac35cc450a07444a30d403957bb549/pack.tar.gz","actions":[{"id":"debian.apt_autoremove","title":"apt autoremove","summary":"Drop packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","description":"Drop packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes possibly many packages, including old kernels.","Triggers prerm/postrm scripts."],"args":[],"examples":[{"title":"Clean up orphaned deps","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["autoremove","-y"]}},{"id":"debian.apt_install","title":"apt install (one package)","summary":"Install ONE named package non-interactively. Its maintainer scripts run as root and typically start or restart the service it ships. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","description":"Install ONE named package non-interactively. Its maintainer scripts run as root and typically start or restart the service it ships. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Downloads from configured sources.","Modifies /var/lib/dpkg.","Triggers postinst scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Install fail2ban","args":{"package":"fail2ban"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["install","-y","--no-install-recommends","{{ args.package }}"]}},{"id":"debian.apt_remove","title":"apt remove (one package)","summary":"Remove ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","description":"Remove ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes binaries from /usr.","Triggers prerm/postrm scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Remove obsolete ftp client","args":{"package":"ftp"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["remove","-y","{{ args.package }}"]}},{"id":"debian.apt_security_check","title":"Pending security upgrades","summary":"List upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","description":"List upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"Are there security patches pending?","args":{}}],"search_terms":["vulnerabilities","cve","unpatched"],"command":{"binary":"/bin/sh","argv":["-c","upgradable=$(apt list --upgradable 2>/dev/null) || { echo \"apt list --upgradable failed\" >&2; exit 1; }\nprintf '%s\\n' \"$upgradable\" | grep -E '\\-security|security\\.(debian|ubuntu)' || echo 'no pending security upgrades'\n"]}},{"id":"debian.apt_update","title":"apt-get update","summary":"Refresh the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","description":"Refresh the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","kind":"exec","risk":"medium","side_effects":["Writes /var/lib/apt/lists/*.","Holds the apt lock briefly.","Outgoing HTTPS to configured sources."],"args":[],"examples":[{"title":"Refresh apt index","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["update","-qq"]}},{"id":"debian.apt_upgradable","title":"List upgradable packages","summary":"List packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","description":"List packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"What needs upgrading?","args":{}}],"search_terms":["pending updates","outdated packages"],"command":{"binary":"apt","argv":["list","--upgradable"]}},{"id":"debian.dpkg_changes","title":"Recent dpkg installs/removes","summary":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","description":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/dpkg.log and its rotated logs (/var/log/dpkg.log.1, /var/log/dpkg.log.*.gz)."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 dpkg log lines","args":{}}],"search_terms":["what changed recently","recent installs","package history"],"command":{"binary":"/bin/sh","argv":["-c","[ -r /var/log/dpkg.log ] || { echo \"no readable dpkg log at /var/log/dpkg.log\" >&2; exit 1; }\nzcat -f /var/log/dpkg.log /var/log/dpkg.log.* 2>/dev/null | sort | tail -n {{ args.lines }}\n"]}},{"id":"debian.dpkg_status","title":"dpkg package status","summary":"Return the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","description":"Return the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/dpkg/status."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Is openssl installed and what version?","args":{"package":"openssl"}}],"search_terms":[],"command":{"binary":"dpkg","argv":["-s","{{ args.package }}"]}},{"id":"debian.kernel_info","title":"Kernel + uptime + reboot-required","summary":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","description":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","kind":"exec","risk":"low","side_effects":["One uname call, one uptime call, stat on /var/run/reboot-required."],"args":[],"examples":[{"title":"Kernel + reboot posture","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","uname -a; uptime; if [ -f /var/run/reboot-required ]; then echo 'reboot-required: yes'; cat /var/run/reboot-required.pkgs 2>/dev/null || true; else echo 'reboot-required: no'; fi"]}}]},{"version":"0.1.9","content_hash":"sha256:760bc196920960092dc4202b554c3c676aac4a39bb80d8fdb556412e7605d743","tarball_url":"https://registry.emisar.dev/v1/packs/debian/0.1.9/760bc196920960092dc4202b554c3c676aac4a39bb80d8fdb556412e7605d743/pack.tar.gz","actions":[{"id":"debian.apt_autoremove","title":"apt autoremove","summary":"Drop packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","description":"Drop packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes possibly many packages, including old kernels.","Triggers prerm/postrm scripts."],"args":[],"examples":[{"title":"Clean up orphaned deps","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["autoremove","-y"]}},{"id":"debian.apt_install","title":"apt install (one package)","summary":"Install ONE named package non-interactively. Its maintainer scripts run as root and typically start or restart the service it ships. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","description":"Install ONE named package non-interactively. Its maintainer scripts run as root and typically start or restart the service it ships. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Downloads from configured sources.","Modifies /var/lib/dpkg.","Triggers postinst scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Install fail2ban","args":{"package":"fail2ban"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["install","-y","--no-install-recommends","{{ args.package }}"]}},{"id":"debian.apt_remove","title":"apt remove (one package)","summary":"Remove ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","description":"Remove ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes binaries from /usr.","Triggers prerm/postrm scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Remove obsolete ftp client","args":{"package":"ftp"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["remove","-y","{{ args.package }}"]}},{"id":"debian.apt_security_check","title":"Pending security upgrades","summary":"List upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","description":"List upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"Are there security patches pending?","args":{}}],"search_terms":["vulnerabilities","cve","unpatched"],"command":{"binary":"/bin/sh","argv":["-c","upgradable=$(apt list --upgradable 2>/dev/null) || { echo \"apt list --upgradable failed\" >&2; exit 1; }\nprintf '%s\\n' \"$upgradable\" | grep -E '\\-security|security\\.(debian|ubuntu)' || echo 'no pending security upgrades'\n"]}},{"id":"debian.apt_update","title":"apt-get update","summary":"Refresh the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","description":"Refresh the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","kind":"exec","risk":"medium","side_effects":["Writes /var/lib/apt/lists/*.","Holds the apt lock briefly.","Outgoing HTTPS to configured sources."],"args":[],"examples":[{"title":"Refresh apt index","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["update","-qq"]}},{"id":"debian.apt_upgradable","title":"List upgradable packages","summary":"List packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","description":"List packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"What needs upgrading?","args":{}}],"search_terms":["pending updates","outdated packages"],"command":{"binary":"apt","argv":["list","--upgradable"]}},{"id":"debian.dpkg_changes","title":"Recent dpkg installs/removes","summary":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","description":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/dpkg.log and its rotated logs (/var/log/dpkg.log.1, /var/log/dpkg.log.*.gz)."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 dpkg log lines","args":{}}],"search_terms":["what changed recently","recent installs","package history"],"command":{"binary":"/bin/sh","argv":["-c","[ -r /var/log/dpkg.log ] || { echo \"no readable dpkg log at /var/log/dpkg.log\" >&2; exit 1; }\nzcat -f /var/log/dpkg.log /var/log/dpkg.log.* 2>/dev/null | sort | tail -n {{ args.lines }}\n"]}},{"id":"debian.dpkg_status","title":"dpkg package status","summary":"Return the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","description":"Return the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/dpkg/status."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Is openssl installed and what version?","args":{"package":"openssl"}}],"search_terms":[],"command":{"binary":"dpkg","argv":["-s","{{ args.package }}"]}},{"id":"debian.kernel_info","title":"Kernel + uptime + reboot-required","summary":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","description":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","kind":"exec","risk":"low","side_effects":["One uname call, one uptime call, stat on /var/run/reboot-required."],"args":[],"examples":[{"title":"Kernel + reboot posture","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","uname -a; uptime; if [ -f /var/run/reboot-required ]; then echo 'reboot-required: yes'; cat /var/run/reboot-required.pkgs 2>/dev/null || true; else echo 'reboot-required: no'; fi"]}}]},{"version":"0.1.7","content_hash":"sha256:54d971e6e1ba47f6a0283dd548924f467cd04820999d8f56174508bb85bd25ac","tarball_url":"https://registry.emisar.dev/v1/packs/debian/0.1.7/54d971e6e1ba47f6a0283dd548924f467cd04820999d8f56174508bb85bd25ac/pack.tar.gz","actions":[{"id":"debian.apt_autoremove","title":"apt autoremove","summary":"Drops packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","description":"Drops packages that were installed as dependencies and are no longer required. Run after a series of removes. Considered high-risk because old kernels and headers are exactly the things autoremove cleans up — verify the running kernel is not on the removal list before approving.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes possibly many packages, including old kernels.","Triggers prerm/postrm scripts."],"args":[],"examples":[{"title":"Clean up orphaned deps","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["autoremove","-y"]}},{"id":"debian.apt_install","title":"apt install (one package)","summary":"Installs ONE named package non-interactively. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","description":"Installs ONE named package non-interactively. Args are restricted to one package — multi-package installs and arbitrary apt flags are intentionally not supported. Verify with `dpkg_status` afterward. Holds the apt lock for the duration; concurrent dpkg/apt operations will queue.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Downloads from configured sources.","Modifies /var/lib/dpkg.","Triggers postinst scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Install fail2ban","args":{"package":"fail2ban"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["install","-y","--no-install-recommends","{{ args.package }}"]}},{"id":"debian.apt_remove","title":"apt remove (one package)","summary":"Removes ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","description":"Removes ONE named package non-interactively. Config files are kept (apt remove, not purge). For data-bearing packages this still drops the binaries — confirm via `dpkg_status` first that you are not removing a service still in use. Holds the apt lock.","kind":"exec","risk":"high","side_effects":["Holds the apt lock.","Removes binaries from /usr.","Triggers prerm/postrm scripts."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Remove obsolete ftp client","args":{"package":"ftp"}}],"search_terms":[],"command":{"binary":"apt-get","argv":["remove","-y","{{ args.package }}"]}},{"id":"debian.apt_security_check","title":"Pending security upgrades","summary":"Lists upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","description":"Lists upgradable packages whose origin matches the security archive (`-security`). Read-only. Use as a one-shot patch-posture check. Requires `unattended-upgrades` or at minimum the security source enabled in /etc/apt/sources.list.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"Are there security patches pending?","args":{}}],"search_terms":["vulnerabilities","cve","unpatched"],"command":{"binary":"/bin/sh","argv":["-c","upgradable=$(apt list --upgradable 2>/dev/null) || { echo \"apt list --upgradable failed\" >&2; exit 1; }\nprintf '%s\\n' \"$upgradable\" | grep -E '\\-security|security\\.(debian|ubuntu)' || echo 'no pending security upgrades'\n"]}},{"id":"debian.apt_update","title":"apt-get update","summary":"Refreshes the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","description":"Refreshes the apt package index from configured sources. Does not upgrade anything. Network-bound, may fail on a host behind a restrictive egress filter. Counts as medium-risk because it touches /var/lib/apt and a stale index can confuse later patching.","kind":"exec","risk":"medium","side_effects":["Writes /var/lib/apt/lists/*.","Holds the apt lock briefly.","Outgoing HTTPS to configured sources."],"args":[],"examples":[{"title":"Refresh apt index","args":{}}],"search_terms":[],"command":{"binary":"apt-get","argv":["update","-qq"]}},{"id":"debian.apt_upgradable","title":"List upgradable packages","summary":"Lists packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","description":"Lists packages that have an upgrade available based on the current apt index. Read-only — does NOT refresh the index. Pair with `apt_update` if you suspect the cache is stale.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/apt/lists.","Briefly takes a shared apt lock."],"args":[],"examples":[{"title":"What needs upgrading?","args":{}}],"search_terms":["pending updates","outdated packages"],"command":{"binary":"apt","argv":["list","--upgradable"]}},{"id":"debian.dpkg_changes","title":"Recent dpkg installs/removes","summary":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","description":"Show recent dpkg install / remove / upgrade activity across /var/log/dpkg.log and its rotated logs (.1 and .*.gz), returned in time order. Use to answer \"what was changed on this host recently?\" before deeper forensics. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/dpkg.log and its rotated logs (/var/log/dpkg.log.1, /var/log/dpkg.log.*.gz)."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 dpkg log lines","args":{}}],"search_terms":["what changed recently","recent installs","package history"],"command":{"binary":"/bin/sh","argv":["-c","[ -r /var/log/dpkg.log ] || { echo \"no readable dpkg log at /var/log/dpkg.log\" >&2; exit 1; }\nzcat -f /var/log/dpkg.log /var/log/dpkg.log.* 2>/dev/null | sort | tail -n {{ args.lines }}\n"]}},{"id":"debian.dpkg_status","title":"dpkg package status","summary":"Returns the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","description":"Returns the dpkg status (installed version, architecture, depends, maintainer) for one named package. Read-only. The package name is pattern-restricted to safe Debian package syntax.","kind":"exec","risk":"low","side_effects":["Reads /var/lib/dpkg/status."],"args":[{"name":"package","type":"string","required":true,"description":"Binary package name.","validation":{"pattern":"^[a-z0-9][a-z0-9.+\\-]{0,62}$"}}],"examples":[{"title":"Is openssl installed and what version?","args":{"package":"openssl"}}],"search_terms":[],"command":{"binary":"dpkg","argv":["-s","{{ args.package }}"]}},{"id":"debian.kernel_info","title":"Kernel + uptime + reboot-required","summary":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","description":"Show kernel version (`uname -a`), uptime, and whether the host has /var/run/reboot-required (set by some packages — most often after a libc or kernel upgrade). Read-only. Use to plan a reboot window.","kind":"exec","risk":"low","side_effects":["One uname call, one uptime call, stat on /var/run/reboot-required."],"args":[],"examples":[{"title":"Kernel + reboot posture","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","uname -a; uptime; if [ -f /var/run/reboot-required ]; then echo 'reboot-required: yes'; cat /var/run/reboot-required.pkgs 2>/dev/null || true; else echo 'reboot-required: no'; fi"]}}]}]},{"id":"debugging","name":"Linux debugging toolkit","version":"0.2.20","description":"General-purpose Linux diagnostics + low-level remediation: process and memory tops, vmstat/iostat snapshots, socket inventories, per-PID inspection, kernel-state checks, network reachability, plus fix-it actions (drop_caches, kill_pid by signal, sysctl_set). Use as the first-touch pack when something is wrong.","vendor":"emisar","homepage":"https://emisar.dev/packs/debugging","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/debugging","content_hash":"sha256:6d513f543e287e9972e79856dcd289ab254007d81460b3db734cfc777de5db7f","tarball_url":"https://registry.emisar.dev/v1/packs/debugging/0.2.20/6d513f543e287e9972e79856dcd289ab254007d81460b3db734cfc777de5db7f/pack.tar.gz","requires":{"os":["linux"],"binaries":["ps","ss"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","notes":["Basic diagnostics such as vmstat, loadavg, ping, and host-permitted process reads work unprivileged. Protected process and kernel state is mapped below."],"host_access":[{"actions":["debugging.netstat_listen","debugging.lsof_port","debugging.top_open_files","debugging.pid_context","debugging.pid_env_keys","debugging.pid_connections","debugging.pid_argv","debugging.pid_environ","debugging.pid_cwd","debugging.pid_fds","debugging.pid_status","debugging.pid_stack","debugging.pid_threads","debugging.pid_limits","debugging.pid_io","debugging.dmesg_tail","debugging.dmesg_oom","debugging.slabtop","debugging.drop_caches","debugging.kill_pid","debugging.sysctl_set"],"requirement":"Inspect other users' processes and protected kernel state, or change host process and kernel state.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-debugging-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Debug actions can read other processes' arguments and environments, kill processes, and change kernel settings."}]}],"verify":"debugging.loadavg"},"actions":[{"id":"debugging.disk_free","title":"df + mounts","summary":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","description":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Filesystem usage snapshot","args":{}}],"search_terms":["disk full","no space left on device","out of space"],"command":{"binary":"df","argv":["-hT"]}},{"id":"debugging.dmesg_oom","title":"OOM-kill events from dmesg","summary":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","description":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[],"examples":[{"title":"Recent OOM kills","args":{}}],"search_terms":["out of memory","process disappeared"],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager; } | grep -i -E 'oom|killed process|out of memory' | tail -30"]}},{"id":"debugging.dmesg_tail","title":"Recent kernel messages","summary":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","description":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","kind":"exec","risk":"medium","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 kernel log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager -n {{ args.lines }}; } | tail -n {{ args.lines }}"]}},{"id":"debugging.drop_caches","title":"echo <n> > /proc/sys/vm/drop_caches","summary":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","description":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","kind":"exec","risk":"high","side_effects":["Page cache emptied (1), or slab caches emptied (2), or both (3).","Brief I/O spike as caches repopulate.","Production read latency increases until warm."],"args":[{"name":"mode","type":"integer","required":true,"description":"1=pagecache, 2=dentries+inodes, 3=both.","validation":{"min":1,"max":3}}],"examples":[{"title":"Drop pagecache only","args":{"mode":1}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sync && echo {{ args.mode }} > /proc/sys/vm/drop_caches"]}},{"id":"debugging.iostat","title":"iostat per-device sample","summary":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","description":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","kind":"exec","risk":"low","side_effects":["One iostat invocation lasting N seconds.","Read-only.","Requires sysstat package."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second device-stats snapshot","args":{}}],"search_terms":["iowait","disk latency"],"command":{"binary":"iostat","argv":["-xz","1","{{ args.samples }}"]}},{"id":"debugging.kernel_taint","title":"Kernel taint state","summary":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","description":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","kind":"exec","risk":"low","side_effects":["Two /proc reads.","Read-only."],"args":[],"examples":[{"title":"Is the kernel tainted?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo \"tainted: $(cat /proc/sys/kernel/tainted)\"\ndoc=/usr/share/doc/linux-doc/admin-guide/tainted-kernels.rst\nif [ -r \"$doc\" ]; then head -50 \"$doc\"; else echo 'flags doc not installed'; fi\n"]}},{"id":"debugging.kill_pid","title":"kill -<signal> <pid>","summary":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","description":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","kind":"exec","risk":"high","side_effects":["Signal delivered.","SIGTERM, SIGINT, SIGHUP allow cleanup.","SIGKILL terminates immediately; open files closed by kernel; pid may be reused."],"args":[{"name":"pid","type":"integer","required":true,"description":"Process ID.","validation":{"min":2,"max":4194304}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGINT","SIGHUP","SIGKILL","SIGUSR1","SIGUSR2","SIGQUIT"]}}],"examples":[{"title":"Graceful term","args":{"pid":12345}},{"title":"Force kill","args":{"pid":12345,"signal":"SIGKILL"}}],"search_terms":["terminate","stuck process","hung process"],"command":{"binary":"kill","argv":["-s","{{ args.signal }}","{{ args.pid }}"]}},{"id":"debugging.loadavg","title":"Load + memory + uptime snapshot","summary":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","description":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","kind":"exec","risk":"low","side_effects":["Three /proc reads.","Read-only."],"args":[],"examples":[{"title":"Quick system snapshot","args":{}}],"search_terms":["sluggish","slow host","feels slow","high load","unresponsive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/loadavg; echo; head -n 8 /proc/meminfo; echo; cat /proc/uptime"]}},{"id":"debugging.lsof_port","title":"Who owns a TCP port?","summary":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","description":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP port number.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Who owns port 8080?","args":{"port":8080}}],"search_terms":["address already in use","port in use","port conflict"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnp 'sport = :{{ args.port }} or dport = :{{ args.port }}'"]}},{"id":"debugging.mem_top","title":"Top processes by RSS","summary":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","description":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 memory hogs","args":{}}],"search_terms":["memory hog","what is eating memory"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,rss,vsz,pcpu,pmem,etime,comm --sort=-rss | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_connections","title":"Established connection summary","summary":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","description":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many peer/state groups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 30 peer/state buckets","args":{}}],"search_terms":["hammering","traffic spike","bandwidth","top talkers"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1, $5}' | sed 's/:[0-9]*$//' | sort | uniq -c | sort -nr | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_listen","title":"Listening sockets","summary":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","description":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"What's listening on this host?","args":{}}],"search_terms":["open ports"],"command":{"binary":"ss","argv":["-tulnp"]}},{"id":"debugging.pid_argv","title":"Process full argument vector","summary":"Show the full argument vector a Linux PID was started with, one argument per line. Arguments often contain tokens, passwords, private URLs, or inline configuration, so this action is high risk and should require explicit approval. Prefer pid_context when executable identity and ancestry are enough.","description":"Show the full argument vector a Linux PID was started with, one argument per line. Arguments often contain tokens, passwords, private URLs, or inline configuration, so this action is high risk and should require explicit approval. Prefer pid_context when executable identity and ancestry are enough.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/cmdline and exposes every argument.","Read-only, but output may contain credentials or other secrets.","The runner's pattern-based redaction is a backstop, not a guarantee."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show the full argv for PID 4321 after approval","args":{"pid":4321}}],"search_terms":["full process command line","process arguments","process argv","daemon flags"],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/cmdline"]}},{"id":"debugging.pid_connections","title":"Process remote socket ownership","summary":"List a bounded ss inventory of connected TCP and UDP sockets owned by one Linux PID. Each line includes protocol/state, local and remote endpoints, and kernel process ownership. Listening sockets and unrelated processes are omitted.","description":"List a bounded ss inventory of connected TCP and UDP sockets owned by one Linux PID. Each line includes protocol/state, local and remote endpoints, and kernel process ownership. Listening sockets and unrelated processes are omitted.","kind":"script","risk":"low","side_effects":["One read-only ss inventory filtered locally to the requested PID.","Output is capped by the validated line limit.","Socket ownership for another user's process normally requires root."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID whose connected sockets should be returned.","validation":{"min":1,"max":4194304}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum matching socket lines to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Show up to fifty remote sockets for PID 4321","args":{"pid":4321}},{"title":"Return only ten matching sockets","args":{"limit":10,"pid":4321}}],"search_terms":["process remote connections","process socket ownership","unexpected consul connection","unexpected nomad connection","rogue process network"]},{"id":"debugging.pid_context","title":"Process identity and parent chain","summary":"Show a compact identity record for one Linux PID: owner, start time, command name, executable, cwd, and a parent chain capped at sixteen entries. Command arguments and environment values are deliberately omitted.","description":"Show a compact identity record for one Linux PID: owner, start time, command name, executable, cwd, and a parent chain capped at sixteen entries. Command arguments and environment values are deliberately omitted.","kind":"script","risk":"low","side_effects":["Reads process metadata with ps and /proc readlink operations.","Parent traversal is capped at sixteen processes.","Read-only and does not expose command arguments or environment values."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Identify PID 4321 and its parents","args":{"pid":4321}}],"search_terms":["rogue process","unexpected daemon","process ancestry","who started this process","process executable cwd owner"]},{"id":"debugging.pid_cwd","title":"Process cwd + exe","summary":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","description":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","kind":"exec","risk":"low","side_effects":["Two /proc readlink calls.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Confirm exe path for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo cwd=$(readlink /proc/{{ args.pid }}/cwd); echo exe=$(readlink /proc/{{ args.pid }}/exe)"]}},{"id":"debugging.pid_env_keys","title":"Process environment variable names","summary":"List only the valid environment variable names inherited by one Linux PID, one per line. Values are never emitted, so this can safely establish that variables such as CONSUL_HTTP_TOKEN or NOMAD_ADDR reached an unexpected process. Use the high-risk pid_environ action only when values are essential.","description":"List only the valid environment variable names inherited by one Linux PID, one per line. Values are never emitted, so this can safely establish that variables such as CONSUL_HTTP_TOKEN or NOMAD_ADDR reached an unexpected process. Use the high-risk pid_environ action only when values are essential.","kind":"script","risk":"low","side_effects":["Reads /proc/<pid>/environ but emits only names matching shell variable syntax.","Environment values are never written to stdout, stderr, or a temporary file.","Read-only; inspecting another user's process normally requires root or CAP_SYS_PTRACE."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List inherited variable names for PID 4321","args":{"pid":4321}}],"search_terms":["inherited environment","inherited consul token","inherited nomad address","CONSUL_HTTP_TOKEN","NOMAD_ADDR","process credentials"]},{"id":"debugging.pid_environ","title":"Process environment","summary":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/environ — requires runner uid to match or root.","Read-only, but exposes the process's full environment (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show env for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/environ"]}},{"id":"debugging.pid_fds","title":"Process open file descriptors","summary":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","description":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","kind":"exec","risk":"low","side_effects":["One ls -l on /proc/<pid>/fd.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List FDs for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ls -l /proc/{{ args.pid }}/fd"]}},{"id":"debugging.pid_io","title":"Process I/O accounting","summary":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","description":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"I/O counters for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"debugging.pid_limits","title":"Resource limits applied to a PID","summary":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","description":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Limits for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/limits"]}},{"id":"debugging.pid_stack","title":"Process kernel stack","summary":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","description":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kernel stack for PID 4321","args":{"pid":4321}}],"search_terms":["uninterruptible sleep","d state"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/stack"]}},{"id":"debugging.pid_status","title":"Process /proc status block","summary":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","description":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"debugging.pid_threads","title":"Per-thread stats for one PID","summary":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","description":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Threads of PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"ps","argv":["-L","-p","{{ args.pid }}","-o","tid,nlwp,policy,priority,pcpu,pmem,stat,wchan,comm"]}},{"id":"debugging.ping_host","title":"Ping a host","summary":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","description":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","kind":"exec","risk":"low","side_effects":["One ping process running for ~N seconds.","Outgoing ICMP to the target."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or IPv4 address.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":4,"description":"Number of echo requests.","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping 1.1.1.1 four times","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable","host down"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-w","10","{{ args.host }}"]}},{"id":"debugging.processes_top","title":"Top processes by CPU","summary":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","description":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 by CPU","args":{}}],"search_terms":["cpu hog","high cpu","cpu spike","runaway process"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,pcpu,pmem,rss,etime,comm --sort=-pcpu | head -n {{ args.limit }}"]}},{"id":"debugging.sar_recent","title":"sar 3-sample CPU snapshot","summary":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","description":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","kind":"exec","risk":"low","side_effects":["One sar invocation running ~15s.","Read-only."],"args":[],"examples":[{"title":"15-second CPU snapshot","args":{}}],"search_terms":[],"command":{"binary":"sar","argv":["-u","5","3"]}},{"id":"debugging.slabtop","title":"Kernel slab cache top consumers","summary":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","description":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","kind":"exec","risk":"low","side_effects":["One slabtop invocation.","Read-only."],"args":[],"examples":[{"title":"Top kernel slab caches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(slabtop -o -s c 2>&1); status=$?; printf '%s\\n' \"$out\" | head -40; exit $status"]}},{"id":"debugging.socket_summary","title":"Socket counts by family + state","summary":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","description":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Socket summary","args":{}}],"search_terms":[],"command":{"binary":"ss","argv":["-s"]}},{"id":"debugging.swap_status","title":"Swap usage summary","summary":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","description":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","kind":"exec","risk":"low","side_effects":["One swapon invocation + a /proc scan.","Read-only."],"args":[],"examples":[{"title":"Swap usage + top swappers","args":{}}],"search_terms":["thrashing"],"command":{"binary":"/bin/sh","argv":["-c","swapon --show; echo; cat /proc/swaps; echo; for f in /proc/[0-9]*/status; do awk '/VmSwap|Name/{printf \"%s %s \",$2,$3}END{print \"\"}' \"$f\" 2>/dev/null; done | sort -k 2 -n -r | head -20"]}},{"id":"debugging.sysctl_set","title":"sysctl -w <key>=<value>","summary":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","description":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","kind":"exec","risk":"high","side_effects":["Kernel tunable updated for current boot.","Effect varies — net buffers, vm overcommit, kernel.panic, etc.","Not persistent across reboot."],"args":[{"name":"key","type":"string","required":true,"description":"sysctl key (e.g., net.ipv4.tcp_max_syn_backlog).","validation":{"pattern":"^[a-z0-9][a-z0-9._\\-]{0,127}$"}},{"name":"value","type":"string","required":true,"description":"New value.","validation":{"pattern":"^[a-zA-Z0-9_:.,\\-/= ]{1,256}$"}}],"examples":[{"title":"Raise SYN backlog","args":{"key":"net.ipv4.tcp_max_syn_backlog","value":"4096"}}],"search_terms":[],"command":{"binary":"sysctl","argv":["-w","{{ args.key }}={{ args.value }}"]}},{"id":"debugging.tcp_retrans_top","title":"TCP connections with retransmits","summary":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","description":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Top retransmitting flows","args":{}}],"search_terms":["retransmissions","packet loss"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnpi state established | awk '/retrans/{print}' | sort -k 5 | head -50"]}},{"id":"debugging.tcp_summary","title":"TCP state counts","summary":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","description":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"TCP states at a glance","args":{}}],"search_terms":["connection flood","syn flood","too many connections"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr"]}},{"id":"debugging.top_open_files","title":"Top processes by open-file count","summary":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","description":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","kind":"exec","risk":"low","side_effects":["One lsof invocation.","Read-only; may be slow on large systems."],"args":[],"examples":[{"title":"Top 20 PIDs by FD count","args":{}}],"search_terms":["too many open files"],"command":{"binary":"/bin/sh","argv":["-c","lsof -F p 2>/dev/null | sort | uniq -c | sort -rn | head -20\nexit ${PIPESTATUS:-0}\n"]}},{"id":"debugging.vmstat","title":"vmstat sample","summary":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","description":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","kind":"exec","risk":"low","side_effects":["One vmstat invocation lasting N seconds.","Read-only."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second snapshot","args":{}}],"search_terms":[],"command":{"binary":"vmstat","argv":["1","{{ args.samples }}"]}}],"previous_versions":[{"version":"0.2.18","content_hash":"sha256:2cf4fa92a582e87db083e8944177462b8dd855f397b3cbecd14087b0ce034bc5","tarball_url":"https://registry.emisar.dev/v1/packs/debugging/0.2.18/2cf4fa92a582e87db083e8944177462b8dd855f397b3cbecd14087b0ce034bc5/pack.tar.gz","actions":[{"id":"debugging.disk_free","title":"df + mounts","summary":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","description":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Filesystem usage snapshot","args":{}}],"search_terms":["disk full","no space left on device","out of space"],"command":{"binary":"df","argv":["-hT"]}},{"id":"debugging.dmesg_oom","title":"OOM-kill events from dmesg","summary":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","description":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[],"examples":[{"title":"Recent OOM kills","args":{}}],"search_terms":["out of memory","process disappeared"],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager; } | grep -i -E 'oom|killed process|out of memory' | tail -30"]}},{"id":"debugging.dmesg_tail","title":"Recent kernel messages","summary":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","description":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 kernel log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager -n {{ args.lines }}; } | tail -n {{ args.lines }}"]}},{"id":"debugging.drop_caches","title":"echo <n> > /proc/sys/vm/drop_caches","summary":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","description":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","kind":"exec","risk":"high","side_effects":["Page cache emptied (1), or slab caches emptied (2), or both (3).","Brief I/O spike as caches repopulate.","Production read latency increases until warm."],"args":[{"name":"mode","type":"integer","required":true,"description":"1=pagecache, 2=dentries+inodes, 3=both.","validation":{"min":1,"max":3}}],"examples":[{"title":"Drop pagecache only","args":{"mode":1}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sync && echo {{ args.mode }} > /proc/sys/vm/drop_caches"]}},{"id":"debugging.iostat","title":"iostat per-device sample","summary":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","description":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","kind":"exec","risk":"low","side_effects":["One iostat invocation lasting N seconds.","Read-only.","Requires sysstat package."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second device-stats snapshot","args":{}}],"search_terms":["iowait","disk latency"],"command":{"binary":"iostat","argv":["-xz","1","{{ args.samples }}"]}},{"id":"debugging.kernel_taint","title":"Kernel taint state","summary":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","description":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","kind":"exec","risk":"low","side_effects":["Two /proc reads.","Read-only."],"args":[],"examples":[{"title":"Is the kernel tainted?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo \"tainted: $(cat /proc/sys/kernel/tainted)\"\ndoc=/usr/share/doc/linux-doc/admin-guide/tainted-kernels.rst\nif [ -r \"$doc\" ]; then head -50 \"$doc\"; else echo 'flags doc not installed'; fi\n"]}},{"id":"debugging.kill_pid","title":"kill -<signal> <pid>","summary":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","description":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","kind":"exec","risk":"high","side_effects":["Signal delivered.","SIGTERM, SIGINT, SIGHUP allow cleanup.","SIGKILL terminates immediately; open files closed by kernel; pid may be reused."],"args":[{"name":"pid","type":"integer","required":true,"description":"Process ID.","validation":{"min":2,"max":4194304}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGINT","SIGHUP","SIGKILL","SIGUSR1","SIGUSR2","SIGQUIT"]}}],"examples":[{"title":"Graceful term","args":{"pid":12345}},{"title":"Force kill","args":{"pid":12345,"signal":"SIGKILL"}}],"search_terms":["terminate","stuck process","hung process"],"command":{"binary":"kill","argv":["-s","{{ args.signal }}","{{ args.pid }}"]}},{"id":"debugging.loadavg","title":"Load + memory + uptime snapshot","summary":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","description":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","kind":"exec","risk":"low","side_effects":["Three /proc reads.","Read-only."],"args":[],"examples":[{"title":"Quick system snapshot","args":{}}],"search_terms":["sluggish","slow host","feels slow","high load","unresponsive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/loadavg; echo; head -n 8 /proc/meminfo; echo; cat /proc/uptime"]}},{"id":"debugging.lsof_port","title":"Who owns a TCP port?","summary":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","description":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP port number.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Who owns port 8080?","args":{"port":8080}}],"search_terms":["address already in use","port in use","port conflict"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnp 'sport = :{{ args.port }} or dport = :{{ args.port }}'"]}},{"id":"debugging.mem_top","title":"Top processes by RSS","summary":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","description":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 memory hogs","args":{}}],"search_terms":["memory hog","what is eating memory"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,rss,vsz,pcpu,pmem,etime,comm --sort=-rss | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_connections","title":"Established connection summary","summary":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","description":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many peer/state groups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 30 peer/state buckets","args":{}}],"search_terms":["hammering","traffic spike","bandwidth","top talkers"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1, $5}' | sed 's/:[0-9]*$//' | sort | uniq -c | sort -nr | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_listen","title":"Listening sockets","summary":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","description":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"What's listening on this host?","args":{}}],"search_terms":["open ports"],"command":{"binary":"ss","argv":["-tulnp"]}},{"id":"debugging.pid_argv","title":"Process full argument vector","summary":"Show the full argument vector a Linux PID was started with, one argument per line. Arguments often contain tokens, passwords, private URLs, or inline configuration, so this action is high risk and should require explicit approval. Prefer pid_context when executable identity and ancestry are enough.","description":"Show the full argument vector a Linux PID was started with, one argument per line. Arguments often contain tokens, passwords, private URLs, or inline configuration, so this action is high risk and should require explicit approval. Prefer pid_context when executable identity and ancestry are enough.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/cmdline and exposes every argument.","Read-only, but output may contain credentials or other secrets.","The runner's pattern-based redaction is a backstop, not a guarantee."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show the full argv for PID 4321 after approval","args":{"pid":4321}}],"search_terms":["full process command line","process arguments","process argv","daemon flags"],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/cmdline"]}},{"id":"debugging.pid_connections","title":"Process remote socket ownership","summary":"List a bounded ss inventory of connected TCP and UDP sockets owned by one Linux PID. Each line includes protocol/state, local and remote endpoints, and kernel process ownership. Listening sockets and unrelated processes are omitted.","description":"List a bounded ss inventory of connected TCP and UDP sockets owned by one Linux PID. Each line includes protocol/state, local and remote endpoints, and kernel process ownership. Listening sockets and unrelated processes are omitted.","kind":"script","risk":"low","side_effects":["One read-only ss inventory filtered locally to the requested PID.","Output is capped by the validated line limit.","Socket ownership for another user's process normally requires root."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID whose connected sockets should be returned.","validation":{"min":1,"max":4194304}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum matching socket lines to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Show up to fifty remote sockets for PID 4321","args":{"pid":4321}},{"title":"Return only ten matching sockets","args":{"limit":10,"pid":4321}}],"search_terms":["process remote connections","process socket ownership","unexpected consul connection","unexpected nomad connection","rogue process network"]},{"id":"debugging.pid_context","title":"Process identity and parent chain","summary":"Show a compact identity record for one Linux PID: owner, start time, command name, executable, cwd, and a parent chain capped at sixteen entries. Command arguments and environment values are deliberately omitted.","description":"Show a compact identity record for one Linux PID: owner, start time, command name, executable, cwd, and a parent chain capped at sixteen entries. Command arguments and environment values are deliberately omitted.","kind":"script","risk":"low","side_effects":["Reads process metadata with ps and /proc readlink operations.","Parent traversal is capped at sixteen processes.","Read-only and does not expose command arguments or environment values."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Identify PID 4321 and its parents","args":{"pid":4321}}],"search_terms":["rogue process","unexpected daemon","process ancestry","who started this process","process executable cwd owner"]},{"id":"debugging.pid_cwd","title":"Process cwd + exe","summary":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","description":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","kind":"exec","risk":"low","side_effects":["Two /proc readlink calls.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Confirm exe path for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo cwd=$(readlink /proc/{{ args.pid }}/cwd); echo exe=$(readlink /proc/{{ args.pid }}/exe)"]}},{"id":"debugging.pid_env_keys","title":"Process environment variable names","summary":"List only the valid environment variable names inherited by one Linux PID, one per line. Values are never emitted, so this can safely establish that variables such as CONSUL_HTTP_TOKEN or NOMAD_ADDR reached an unexpected process. Use the high-risk pid_environ action only when values are essential.","description":"List only the valid environment variable names inherited by one Linux PID, one per line. Values are never emitted, so this can safely establish that variables such as CONSUL_HTTP_TOKEN or NOMAD_ADDR reached an unexpected process. Use the high-risk pid_environ action only when values are essential.","kind":"script","risk":"low","side_effects":["Reads /proc/<pid>/environ but emits only names matching shell variable syntax.","Environment values are never written to stdout, stderr, or a temporary file.","Read-only; inspecting another user's process normally requires root or CAP_SYS_PTRACE."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List inherited variable names for PID 4321","args":{"pid":4321}}],"search_terms":["inherited environment","inherited consul token","inherited nomad address","CONSUL_HTTP_TOKEN","NOMAD_ADDR","process credentials"]},{"id":"debugging.pid_environ","title":"Process environment","summary":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/environ — requires runner uid to match or root.","Read-only, but exposes the process's full environment (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show env for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/environ"]}},{"id":"debugging.pid_fds","title":"Process open file descriptors","summary":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","description":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","kind":"exec","risk":"low","side_effects":["One ls -l on /proc/<pid>/fd.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List FDs for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ls -l /proc/{{ args.pid }}/fd"]}},{"id":"debugging.pid_io","title":"Process I/O accounting","summary":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","description":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"I/O counters for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"debugging.pid_limits","title":"Resource limits applied to a PID","summary":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","description":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Limits for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/limits"]}},{"id":"debugging.pid_stack","title":"Process kernel stack","summary":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","description":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kernel stack for PID 4321","args":{"pid":4321}}],"search_terms":["uninterruptible sleep","d state"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/stack"]}},{"id":"debugging.pid_status","title":"Process /proc status block","summary":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","description":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"debugging.pid_threads","title":"Per-thread stats for one PID","summary":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","description":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Threads of PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"ps","argv":["-L","-p","{{ args.pid }}","-o","tid,nlwp,policy,priority,pcpu,pmem,stat,wchan,comm"]}},{"id":"debugging.ping_host","title":"Ping a host","summary":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","description":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","kind":"exec","risk":"low","side_effects":["One ping process running for ~N seconds.","Outgoing ICMP to the target."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or IPv4 address.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":4,"description":"Number of echo requests.","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping 1.1.1.1 four times","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable","host down"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-w","10","{{ args.host }}"]}},{"id":"debugging.processes_top","title":"Top processes by CPU","summary":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","description":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 by CPU","args":{}}],"search_terms":["cpu hog","high cpu","cpu spike","runaway process"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,pcpu,pmem,rss,etime,comm --sort=-pcpu | head -n {{ args.limit }}"]}},{"id":"debugging.sar_recent","title":"sar 3-sample CPU snapshot","summary":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","description":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","kind":"exec","risk":"low","side_effects":["One sar invocation running ~15s.","Read-only."],"args":[],"examples":[{"title":"15-second CPU snapshot","args":{}}],"search_terms":[],"command":{"binary":"sar","argv":["-u","5","3"]}},{"id":"debugging.slabtop","title":"Kernel slab cache top consumers","summary":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","description":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","kind":"exec","risk":"low","side_effects":["One slabtop invocation.","Read-only."],"args":[],"examples":[{"title":"Top kernel slab caches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(slabtop -o -s c 2>&1); status=$?; printf '%s\\n' \"$out\" | head -40; exit $status"]}},{"id":"debugging.socket_summary","title":"Socket counts by family + state","summary":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","description":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Socket summary","args":{}}],"search_terms":[],"command":{"binary":"ss","argv":["-s"]}},{"id":"debugging.swap_status","title":"Swap usage summary","summary":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","description":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","kind":"exec","risk":"low","side_effects":["One swapon invocation + a /proc scan.","Read-only."],"args":[],"examples":[{"title":"Swap usage + top swappers","args":{}}],"search_terms":["thrashing"],"command":{"binary":"/bin/sh","argv":["-c","swapon --show; echo; cat /proc/swaps; echo; for f in /proc/[0-9]*/status; do awk '/VmSwap|Name/{printf \"%s %s \",$2,$3}END{print \"\"}' \"$f\" 2>/dev/null; done | sort -k 2 -n -r | head -20"]}},{"id":"debugging.sysctl_set","title":"sysctl -w <key>=<value>","summary":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","description":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","kind":"exec","risk":"high","side_effects":["Kernel tunable updated for current boot.","Effect varies — net buffers, vm overcommit, kernel.panic, etc.","Not persistent across reboot."],"args":[{"name":"key","type":"string","required":true,"description":"sysctl key (e.g., net.ipv4.tcp_max_syn_backlog).","validation":{"pattern":"^[a-z0-9][a-z0-9._\\-]{0,127}$"}},{"name":"value","type":"string","required":true,"description":"New value.","validation":{"pattern":"^[a-zA-Z0-9_:.,\\-/= ]{1,256}$"}}],"examples":[{"title":"Raise SYN backlog","args":{"key":"net.ipv4.tcp_max_syn_backlog","value":"4096"}}],"search_terms":[],"command":{"binary":"sysctl","argv":["-w","{{ args.key }}={{ args.value }}"]}},{"id":"debugging.tcp_retrans_top","title":"TCP connections with retransmits","summary":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","description":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Top retransmitting flows","args":{}}],"search_terms":["retransmissions","packet loss"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnpi state established | awk '/retrans/{print}' | sort -k 5 | head -50"]}},{"id":"debugging.tcp_summary","title":"TCP state counts","summary":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","description":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"TCP states at a glance","args":{}}],"search_terms":["connection flood","syn flood","too many connections"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr"]}},{"id":"debugging.top_open_files","title":"Top processes by open-file count","summary":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","description":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","kind":"exec","risk":"low","side_effects":["One lsof invocation.","Read-only; may be slow on large systems."],"args":[],"examples":[{"title":"Top 20 PIDs by FD count","args":{}}],"search_terms":["too many open files"],"command":{"binary":"/bin/sh","argv":["-c","lsof -F p 2>/dev/null | sort | uniq -c | sort -rn | head -20\nexit ${PIPESTATUS:-0}\n"]}},{"id":"debugging.vmstat","title":"vmstat sample","summary":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","description":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","kind":"exec","risk":"low","side_effects":["One vmstat invocation lasting N seconds.","Read-only."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second snapshot","args":{}}],"search_terms":[],"command":{"binary":"vmstat","argv":["1","{{ args.samples }}"]}}]},{"version":"0.2.17","content_hash":"sha256:cfc2f6aa83108c16bb2256f79dd01cbd03c068c686f5d6ca8749882084b19775","tarball_url":"https://registry.emisar.dev/v1/packs/debugging/0.2.17/cfc2f6aa83108c16bb2256f79dd01cbd03c068c686f5d6ca8749882084b19775/pack.tar.gz","actions":[{"id":"debugging.disk_free","title":"df + mounts","summary":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","description":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Filesystem usage snapshot","args":{}}],"search_terms":["disk full","no space left on device","out of space"],"command":{"binary":"df","argv":["-hT"]}},{"id":"debugging.dmesg_oom","title":"OOM-kill events from dmesg","summary":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","description":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[],"examples":[{"title":"Recent OOM kills","args":{}}],"search_terms":["out of memory","process disappeared"],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager; } | grep -i -E 'oom|killed process|out of memory' | tail -30"]}},{"id":"debugging.dmesg_tail","title":"Recent kernel messages","summary":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","description":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 kernel log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager -n {{ args.lines }}; } | tail -n {{ args.lines }}"]}},{"id":"debugging.drop_caches","title":"echo <n> > /proc/sys/vm/drop_caches","summary":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","description":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","kind":"exec","risk":"high","side_effects":["Page cache emptied (1), or slab caches emptied (2), or both (3).","Brief I/O spike as caches repopulate.","Production read latency increases until warm."],"args":[{"name":"mode","type":"integer","required":true,"description":"1=pagecache, 2=dentries+inodes, 3=both.","validation":{"min":1,"max":3}}],"examples":[{"title":"Drop pagecache only","args":{"mode":1}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sync && echo {{ args.mode }} > /proc/sys/vm/drop_caches"]}},{"id":"debugging.iostat","title":"iostat per-device sample","summary":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","description":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","kind":"exec","risk":"low","side_effects":["One iostat invocation lasting N seconds.","Read-only.","Requires sysstat package."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second device-stats snapshot","args":{}}],"search_terms":["iowait","disk latency"],"command":{"binary":"iostat","argv":["-xz","1","{{ args.samples }}"]}},{"id":"debugging.kernel_taint","title":"Kernel taint state","summary":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","description":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","kind":"exec","risk":"low","side_effects":["Two /proc reads.","Read-only."],"args":[],"examples":[{"title":"Is the kernel tainted?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo \"tainted: $(cat /proc/sys/kernel/tainted)\"\ndoc=/usr/share/doc/linux-doc/admin-guide/tainted-kernels.rst\nif [ -r \"$doc\" ]; then head -50 \"$doc\"; else echo 'flags doc not installed'; fi\n"]}},{"id":"debugging.kill_pid","title":"kill -<signal> <pid>","summary":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","description":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","kind":"exec","risk":"high","side_effects":["Signal delivered.","SIGTERM, SIGINT, SIGHUP allow cleanup.","SIGKILL terminates immediately; open files closed by kernel; pid may be reused."],"args":[{"name":"pid","type":"integer","required":true,"description":"Process ID.","validation":{"min":2,"max":4194304}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGINT","SIGHUP","SIGKILL","SIGUSR1","SIGUSR2","SIGQUIT"]}}],"examples":[{"title":"Graceful term","args":{"pid":12345}},{"title":"Force kill","args":{"pid":12345,"signal":"SIGKILL"}}],"search_terms":["terminate","stuck process","hung process"],"command":{"binary":"kill","argv":["-s","{{ args.signal }}","{{ args.pid }}"]}},{"id":"debugging.loadavg","title":"Load + memory + uptime snapshot","summary":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","description":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","kind":"exec","risk":"low","side_effects":["Three /proc reads.","Read-only."],"args":[],"examples":[{"title":"Quick system snapshot","args":{}}],"search_terms":["sluggish","slow host","feels slow","high load","unresponsive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/loadavg; echo; head -n 8 /proc/meminfo; echo; cat /proc/uptime"]}},{"id":"debugging.lsof_port","title":"Who owns a TCP port?","summary":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","description":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP port number.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Who owns port 8080?","args":{"port":8080}}],"search_terms":["address already in use","port in use","port conflict"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnp 'sport = :{{ args.port }} or dport = :{{ args.port }}'"]}},{"id":"debugging.mem_top","title":"Top processes by RSS","summary":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","description":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 memory hogs","args":{}}],"search_terms":["memory hog","what is eating memory"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,rss,vsz,pcpu,pmem,etime,comm --sort=-rss | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_connections","title":"Established connection summary","summary":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","description":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many peer/state groups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 30 peer/state buckets","args":{}}],"search_terms":["hammering","traffic spike","bandwidth","top talkers"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1, $5}' | sed 's/:[0-9]*$//' | sort | uniq -c | sort -nr | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_listen","title":"Listening sockets","summary":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","description":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"What's listening on this host?","args":{}}],"search_terms":["open ports"],"command":{"binary":"ss","argv":["-tulnp"]}},{"id":"debugging.pid_argv","title":"Process full argument vector","summary":"Show the full argument vector a Linux PID was started with, one argument per line. Arguments often contain tokens, passwords, private URLs, or inline configuration, so this action is high risk and should require explicit approval. Prefer pid_context when executable identity and ancestry are enough.","description":"Show the full argument vector a Linux PID was started with, one argument per line. Arguments often contain tokens, passwords, private URLs, or inline configuration, so this action is high risk and should require explicit approval. Prefer pid_context when executable identity and ancestry are enough.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/cmdline and exposes every argument.","Read-only, but output may contain credentials or other secrets.","The runner's pattern-based redaction is a backstop, not a guarantee."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show the full argv for PID 4321 after approval","args":{"pid":4321}}],"search_terms":["full process command line","process arguments","process argv","daemon flags"],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/cmdline"]}},{"id":"debugging.pid_connections","title":"Process remote socket ownership","summary":"List a bounded ss inventory of connected TCP and UDP sockets owned by one Linux PID. Each line includes protocol/state, local and remote endpoints, and kernel process ownership. Listening sockets and unrelated processes are omitted.","description":"List a bounded ss inventory of connected TCP and UDP sockets owned by one Linux PID. Each line includes protocol/state, local and remote endpoints, and kernel process ownership. Listening sockets and unrelated processes are omitted.","kind":"script","risk":"low","side_effects":["One read-only ss inventory filtered locally to the requested PID.","Output is capped by the validated line limit.","Socket ownership for another user's process normally requires root."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID whose connected sockets should be returned.","validation":{"min":1,"max":4194304}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum matching socket lines to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Show up to fifty remote sockets for PID 4321","args":{"pid":4321}},{"title":"Return only ten matching sockets","args":{"limit":10,"pid":4321}}],"search_terms":["process remote connections","process socket ownership","unexpected consul connection","unexpected nomad connection","rogue process network"]},{"id":"debugging.pid_context","title":"Process identity and parent chain","summary":"Show a compact identity record for one Linux PID: owner, start time, command name, executable, cwd, and a parent chain capped at sixteen entries. Command arguments and environment values are deliberately omitted.","description":"Show a compact identity record for one Linux PID: owner, start time, command name, executable, cwd, and a parent chain capped at sixteen entries. Command arguments and environment values are deliberately omitted.","kind":"script","risk":"low","side_effects":["Reads process metadata with ps and /proc readlink operations.","Parent traversal is capped at sixteen processes.","Read-only and does not expose command arguments or environment values."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Identify PID 4321 and its parents","args":{"pid":4321}}],"search_terms":["rogue process","unexpected daemon","process ancestry","who started this process","process executable cwd owner"]},{"id":"debugging.pid_cwd","title":"Process cwd + exe","summary":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","description":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","kind":"exec","risk":"low","side_effects":["Two /proc readlink calls.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Confirm exe path for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo cwd=$(readlink /proc/{{ args.pid }}/cwd); echo exe=$(readlink /proc/{{ args.pid }}/exe)"]}},{"id":"debugging.pid_env_keys","title":"Process environment variable names","summary":"List only the valid environment variable names inherited by one Linux PID, one per line. Values are never emitted, so this can safely establish that variables such as CONSUL_HTTP_TOKEN or NOMAD_ADDR reached an unexpected process. Use the high-risk pid_environ action only when values are essential.","description":"List only the valid environment variable names inherited by one Linux PID, one per line. Values are never emitted, so this can safely establish that variables such as CONSUL_HTTP_TOKEN or NOMAD_ADDR reached an unexpected process. Use the high-risk pid_environ action only when values are essential.","kind":"script","risk":"low","side_effects":["Reads /proc/<pid>/environ but emits only names matching shell variable syntax.","Environment values are never written to stdout, stderr, or a temporary file.","Read-only; inspecting another user's process normally requires root or CAP_SYS_PTRACE."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List inherited variable names for PID 4321","args":{"pid":4321}}],"search_terms":["inherited environment","inherited consul token","inherited nomad address","CONSUL_HTTP_TOKEN","NOMAD_ADDR","process credentials"]},{"id":"debugging.pid_environ","title":"Process environment","summary":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/environ — requires runner uid to match or root.","Read-only, but exposes the process's full environment (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show env for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/environ"]}},{"id":"debugging.pid_fds","title":"Process open file descriptors","summary":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","description":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","kind":"exec","risk":"low","side_effects":["One ls -l on /proc/<pid>/fd.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List FDs for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ls -l /proc/{{ args.pid }}/fd"]}},{"id":"debugging.pid_io","title":"Process I/O accounting","summary":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","description":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"I/O counters for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"debugging.pid_limits","title":"Resource limits applied to a PID","summary":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","description":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Limits for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/limits"]}},{"id":"debugging.pid_stack","title":"Process kernel stack","summary":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","description":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kernel stack for PID 4321","args":{"pid":4321}}],"search_terms":["uninterruptible sleep","d state"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/stack"]}},{"id":"debugging.pid_status","title":"Process /proc status block","summary":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","description":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"debugging.pid_threads","title":"Per-thread stats for one PID","summary":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","description":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Threads of PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"ps","argv":["-L","-p","{{ args.pid }}","-o","tid,nlwp,policy,priority,pcpu,pmem,stat,wchan,comm"]}},{"id":"debugging.ping_host","title":"Ping a host","summary":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","description":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","kind":"exec","risk":"low","side_effects":["One ping process running for ~N seconds.","Outgoing ICMP to the target."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or IPv4 address.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":4,"description":"Number of echo requests.","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping 1.1.1.1 four times","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable","host down"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-w","10","{{ args.host }}"]}},{"id":"debugging.processes_top","title":"Top processes by CPU","summary":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","description":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 by CPU","args":{}}],"search_terms":["cpu hog","high cpu","cpu spike","runaway process"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,pcpu,pmem,rss,etime,comm --sort=-pcpu | head -n {{ args.limit }}"]}},{"id":"debugging.sar_recent","title":"sar 3-sample CPU snapshot","summary":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","description":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","kind":"exec","risk":"low","side_effects":["One sar invocation running ~15s.","Read-only."],"args":[],"examples":[{"title":"15-second CPU snapshot","args":{}}],"search_terms":[],"command":{"binary":"sar","argv":["-u","5","3"]}},{"id":"debugging.slabtop","title":"Kernel slab cache top consumers","summary":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","description":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","kind":"exec","risk":"low","side_effects":["One slabtop invocation.","Read-only."],"args":[],"examples":[{"title":"Top kernel slab caches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(slabtop -o -s c 2>&1); status=$?; printf '%s\\n' \"$out\" | head -40; exit $status"]}},{"id":"debugging.socket_summary","title":"Socket counts by family + state","summary":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","description":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Socket summary","args":{}}],"search_terms":[],"command":{"binary":"ss","argv":["-s"]}},{"id":"debugging.swap_status","title":"Swap usage summary","summary":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","description":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","kind":"exec","risk":"low","side_effects":["One swapon invocation + a /proc scan.","Read-only."],"args":[],"examples":[{"title":"Swap usage + top swappers","args":{}}],"search_terms":["thrashing"],"command":{"binary":"/bin/sh","argv":["-c","swapon --show; echo; cat /proc/swaps; echo; for f in /proc/[0-9]*/status; do awk '/VmSwap|Name/{printf \"%s %s \",$2,$3}END{print \"\"}' \"$f\" 2>/dev/null; done | sort -k 2 -n -r | head -20"]}},{"id":"debugging.sysctl_set","title":"sysctl -w <key>=<value>","summary":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","description":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","kind":"exec","risk":"high","side_effects":["Kernel tunable updated for current boot.","Effect varies — net buffers, vm overcommit, kernel.panic, etc.","Not persistent across reboot."],"args":[{"name":"key","type":"string","required":true,"description":"sysctl key (e.g., net.ipv4.tcp_max_syn_backlog).","validation":{"pattern":"^[a-z0-9][a-z0-9._\\-]{0,127}$"}},{"name":"value","type":"string","required":true,"description":"New value.","validation":{"pattern":"^[a-zA-Z0-9_:.,\\-/= ]{1,256}$"}}],"examples":[{"title":"Raise SYN backlog","args":{"key":"net.ipv4.tcp_max_syn_backlog","value":"4096"}}],"search_terms":[],"command":{"binary":"sysctl","argv":["-w","{{ args.key }}={{ args.value }}"]}},{"id":"debugging.tcp_retrans_top","title":"TCP connections with retransmits","summary":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","description":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Top retransmitting flows","args":{}}],"search_terms":["retransmissions","packet loss"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnpi state established | awk '/retrans/{print}' | sort -k 5 | head -50"]}},{"id":"debugging.tcp_summary","title":"TCP state counts","summary":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","description":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"TCP states at a glance","args":{}}],"search_terms":["connection flood","syn flood","too many connections"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr"]}},{"id":"debugging.top_open_files","title":"Top processes by open-file count","summary":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","description":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","kind":"exec","risk":"low","side_effects":["One lsof invocation.","Read-only; may be slow on large systems."],"args":[],"examples":[{"title":"Top 20 PIDs by FD count","args":{}}],"search_terms":["too many open files"],"command":{"binary":"/bin/sh","argv":["-c","lsof -F p 2>/dev/null | sort | uniq -c | sort -rn | head -20\nexit ${PIPESTATUS:-0}\n"]}},{"id":"debugging.vmstat","title":"vmstat sample","summary":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","description":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","kind":"exec","risk":"low","side_effects":["One vmstat invocation lasting N seconds.","Read-only."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second snapshot","args":{}}],"search_terms":[],"command":{"binary":"vmstat","argv":["1","{{ args.samples }}"]}}]},{"version":"0.2.16","content_hash":"sha256:1876dca63c11974f0900136ebe1494b60475ecaa7e1fb61689adf76f77c05ea4","tarball_url":"https://registry.emisar.dev/v1/packs/debugging/0.2.16/1876dca63c11974f0900136ebe1494b60475ecaa7e1fb61689adf76f77c05ea4/pack.tar.gz","actions":[{"id":"debugging.disk_free","title":"df + mounts","summary":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","description":"Return `df -hT` output. Filesystem type, size, used, avail, and mountpoint for every mounted filesystem. Use as the first check when a write fails with ENOSPC or when /var/log has gone dark.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Filesystem usage snapshot","args":{}}],"search_terms":["disk full","no space left on device","out of space"],"command":{"binary":"df","argv":["-hT"]}},{"id":"debugging.dmesg_oom","title":"OOM-kill events from dmesg","summary":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","description":"Filter dmesg for OOM-killer events. Returns the kernel log lines showing process id, name, RSS, and OOM score for every killed process. The \"why did mysqld vanish?\" answer. Falls back to `journalctl -k` when dmesg is not permitted (needs CAP_SYSLOG / root, or journal read access via systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[],"examples":[{"title":"Recent OOM kills","args":{}}],"search_terms":["out of memory","process disappeared"],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager; } | grep -i -E 'oom|killed process|out of memory' | tail -30"]}},{"id":"debugging.dmesg_tail","title":"Recent kernel messages","summary":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","description":"Return the last N kernel log lines. Surfaces OOM kills, hardware errors, network link flaps, and dropped packets. Reads the kernel ring buffer via dmesg; when that is not permitted (modern kernels gate it behind CAP_SYSLOG) it falls back to `journalctl -k`, which works when the runner can read the journal (root, or a member of systemd-journal / adm). Read-only.","kind":"exec","risk":"low","side_effects":["One dmesg (or journalctl -k) invocation.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 kernel log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ dmesg -T 2>/dev/null || journalctl -k --no-pager -n {{ args.lines }}; } | tail -n {{ args.lines }}"]}},{"id":"debugging.drop_caches","title":"echo <n> > /proc/sys/vm/drop_caches","summary":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","description":"Force the kernel to drop pagecache / dentries / inodes. Use only when a benchmark or memory-fragmentation test requires a cold cache — never on prod for \"I want more free RAM\". Production RSS appears to drop briefly, then the cache repopulates and the next workload is slower until it warms back up.","kind":"exec","risk":"high","side_effects":["Page cache emptied (1), or slab caches emptied (2), or both (3).","Brief I/O spike as caches repopulate.","Production read latency increases until warm."],"args":[{"name":"mode","type":"integer","required":true,"description":"1=pagecache, 2=dentries+inodes, 3=both.","validation":{"min":1,"max":3}}],"examples":[{"title":"Drop pagecache only","args":{"mode":1}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sync && echo {{ args.mode }} > /proc/sys/vm/drop_caches"]}},{"id":"debugging.iostat","title":"iostat per-device sample","summary":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","description":"Run `iostat -xz 1 N` to capture N one-second samples of extended per-device statistics. Surfaces await, %util, queue depth. Use to prove or disprove \"the disk is slow\" before chasing application code.","kind":"exec","risk":"low","side_effects":["One iostat invocation lasting N seconds.","Read-only.","Requires sysstat package."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second device-stats snapshot","args":{}}],"search_terms":["iowait","disk latency"],"command":{"binary":"iostat","argv":["-xz","1","{{ args.samples }}"]}},{"id":"debugging.kernel_taint","title":"Kernel taint state","summary":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","description":"Read /proc/sys/kernel/tainted. A non-zero value means a binary module, a proprietary driver, or a kernel crash has compromised the integrity of the running kernel. The number is a bitmask; this action returns both the raw value and the decoded flags.","kind":"exec","risk":"low","side_effects":["Two /proc reads.","Read-only."],"args":[],"examples":[{"title":"Is the kernel tainted?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo \"tainted: $(cat /proc/sys/kernel/tainted)\"\ndoc=/usr/share/doc/linux-doc/admin-guide/tainted-kernels.rst\nif [ -r \"$doc\" ]; then head -50 \"$doc\"; else echo 'flags doc not installed'; fi\n"]}},{"id":"debugging.kill_pid","title":"kill -<signal> <pid>","summary":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","description":"Send a signal to one process by PID. SIGTERM is the polite default — the process gets a chance to flush state. SIGKILL is unrecoverable — use only when SIGTERM is ignored. Watch for PID reuse: confirm the target via `pid_status` first.","kind":"exec","risk":"high","side_effects":["Signal delivered.","SIGTERM, SIGINT, SIGHUP allow cleanup.","SIGKILL terminates immediately; open files closed by kernel; pid may be reused."],"args":[{"name":"pid","type":"integer","required":true,"description":"Process ID.","validation":{"min":2,"max":4194304}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGINT","SIGHUP","SIGKILL","SIGUSR1","SIGUSR2","SIGQUIT"]}}],"examples":[{"title":"Graceful term","args":{"pid":12345}},{"title":"Force kill","args":{"pid":12345,"signal":"SIGKILL"}}],"search_terms":["terminate","stuck process","hung process"],"command":{"binary":"kill","argv":["-s","{{ args.signal }}","{{ args.pid }}"]}},{"id":"debugging.loadavg","title":"Load + memory + uptime snapshot","summary":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","description":"Read /proc/loadavg, /proc/meminfo, and /proc/uptime to produce a one-shot system snapshot. Cheap. Use as the very first check when triaging a host alert.","kind":"exec","risk":"low","side_effects":["Three /proc reads.","Read-only."],"args":[],"examples":[{"title":"Quick system snapshot","args":{}}],"search_terms":["sluggish","slow host","feels slow","high load","unresponsive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/loadavg; echo; head -n 8 /proc/meminfo; echo; cat /proc/uptime"]}},{"id":"debugging.lsof_port","title":"Who owns a TCP port?","summary":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","description":"Return the PID/process that has a given TCP port open (listening or connected), via `ss -tnp` (not lsof, despite the name). Use to answer \"EADDRINUSE: who's on 8080?\" or to confirm a stuck connection to an upstream. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP port number.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Who owns port 8080?","args":{"port":8080}}],"search_terms":["address already in use","port in use","port conflict"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnp 'sport = :{{ args.port }} or dport = :{{ args.port }}'"]}},{"id":"debugging.mem_top","title":"Top processes by RSS","summary":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","description":"Return the top N processes sorted by resident-set size (RSS). Use when /proc/meminfo or `free` shows pressure and you need the offender. RSS does not double-count shared pages, so a \"leak\" candidate showing high RSS is worth investigating.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 memory hogs","args":{}}],"search_terms":["memory hog","what is eating memory"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,rss,vsz,pcpu,pmem,etime,comm --sort=-rss | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_connections","title":"Established connection summary","summary":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","description":"Return counts of TCP connections grouped by remote peer + state. Useful for spotting connection storms (single host) or TIME_WAIT pressure. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many peer/state groups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 30 peer/state buckets","args":{}}],"search_terms":["hammering","traffic spike","bandwidth","top talkers"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1, $5}' | sed 's/:[0-9]*$//' | sort | uniq -c | sort -nr | head -n {{ args.limit }}"]}},{"id":"debugging.netstat_listen","title":"Listening sockets","summary":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","description":"Return TCP and UDP listening sockets with the owning process (`ss -tulnp`). Use to confirm whether an expected daemon is actually bound and on which interfaces. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"What's listening on this host?","args":{}}],"search_terms":["open ports"],"command":{"binary":"ss","argv":["-tulnp"]}},{"id":"debugging.pid_cwd","title":"Process cwd + exe","summary":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","description":"Return the working directory and executable path of a PID. Use before drawing conclusions from a process name — `nginx` could be any of several binaries depending on PATH order.","kind":"exec","risk":"low","side_effects":["Two /proc readlink calls.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Confirm exe path for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo cwd=$(readlink /proc/{{ args.pid }}/cwd); echo exe=$(readlink /proc/{{ args.pid }}/exe)"]}},{"id":"debugging.pid_environ","title":"Process environment","summary":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full set of environment variables a PID was started with — reads /proc/<pid>/environ and turns NULs into newlines. This deliberately surfaces the process's entire environment, which commonly carries injected secrets (DB URLs, API keys, cloud credentials); scope it by policy and prefer pid_status / pid_limits when you don't need the values. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads /proc/<pid>/environ — requires runner uid to match or root.","Read-only, but exposes the process's full environment (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Show env for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tr '\\0' '\\n' < /proc/{{ args.pid }}/environ"]}},{"id":"debugging.pid_fds","title":"Process open file descriptors","summary":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","description":"List what each FD in /proc/<pid>/fd points at. Sockets show up as `socket:[N]`, files as their path. Use to spot FD-leak candidates or confirm a daemon has the log file you expect.","kind":"exec","risk":"low","side_effects":["One ls -l on /proc/<pid>/fd.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"List FDs for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ls -l /proc/{{ args.pid }}/fd"]}},{"id":"debugging.pid_io","title":"Process I/O accounting","summary":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","description":"Read /proc/<pid>/io — bytes read/written (logical + physical), syscall counts, cancelled writes. Use to find which process is driving disk I/O. Pair with `debugging.iostat` for the disk side.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"I/O counters for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"debugging.pid_limits","title":"Resource limits applied to a PID","summary":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","description":"Read /proc/<pid>/limits — every ulimit applied (open files, stack size, NPROC, memlock, msgqueue, niceness). Use to confirm whether a process is actually getting the higher limits its service file requested.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Limits for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/limits"]}},{"id":"debugging.pid_stack","title":"Process kernel stack","summary":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","description":"Read /proc/<pid>/stack — the current kernel-side stack trace. Use to find what syscall a stuck process is hung in (futex, read, write, lock_kernel). Needs CAP_SYS_ADMIN or root to read.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kernel stack for PID 4321","args":{"pid":4321}}],"search_terms":["uninterruptible sleep","d state"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/stack"]}},{"id":"debugging.pid_status","title":"Process /proc status block","summary":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","description":"Dump /proc/<pid>/status — capabilities, uid/gid, signal masks, RSS, peak RSS, voluntary/involuntary context switches, OOM score. More detail than `ps` for one PID. Read-only.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"debugging.pid_threads","title":"Per-thread stats for one PID","summary":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","description":"List every thread of one PID with CPU%, policy, priority, comm name. Use when one PID's CPU is high but it's unclear which thread inside it is hot. Read-only.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID to inspect.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Threads of PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"ps","argv":["-L","-p","{{ args.pid }}","-o","tid,nlwp,policy,priority,pcpu,pmem,stat,wchan,comm"]}},{"id":"debugging.ping_host","title":"Ping a host","summary":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","description":"Send N ICMP echo requests to a target. Use to confirm L3 reachability when a higher-layer probe (TCP/HTTP) fails. Target is pattern-restricted to safe hostname/IPv4 characters to prevent argument injection.","kind":"exec","risk":"low","side_effects":["One ping process running for ~N seconds.","Outgoing ICMP to the target."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or IPv4 address.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":4,"description":"Number of echo requests.","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping 1.1.1.1 four times","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable","host down"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-w","10","{{ args.host }}"]}},{"id":"debugging.processes_top","title":"Top processes by CPU","summary":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","description":"Return the top N processes sorted by CPU%. Standard `ps` output — pid, user, %cpu, %mem, rss, command. Use as a first-touch check before going deeper with per-PID inspection.","kind":"exec","risk":"low","side_effects":["One ps invocation.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"How many processes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Top 25 by CPU","args":{}}],"search_terms":["cpu hog","high cpu","cpu spike","runaway process"],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,pcpu,pmem,rss,etime,comm --sort=-pcpu | head -n {{ args.limit }}"]}},{"id":"debugging.sar_recent","title":"sar 3-sample CPU snapshot","summary":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","description":"`sar -u 5 3` — three 5-second CPU utilization samples. Surfaces user/system/iowait/steal/idle split with statistical smoothing. Use when `vmstat`'s noise hides the signal. Requires the sysstat package.","kind":"exec","risk":"low","side_effects":["One sar invocation running ~15s.","Read-only."],"args":[],"examples":[{"title":"15-second CPU snapshot","args":{}}],"search_terms":[],"command":{"binary":"sar","argv":["-u","5","3"]}},{"id":"debugging.slabtop","title":"Kernel slab cache top consumers","summary":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","description":"`slabtop -o -s c | head -40` — top 40 kernel slab caches by cache size. Use when /proc/meminfo shows high `Slab` but no userland process accounts for the memory. dentry / inode pressure is the usual answer.","kind":"exec","risk":"low","side_effects":["One slabtop invocation.","Read-only."],"args":[],"examples":[{"title":"Top kernel slab caches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(slabtop -o -s c 2>&1); status=$?; printf '%s\\n' \"$out\" | head -40; exit $status"]}},{"id":"debugging.socket_summary","title":"Socket counts by family + state","summary":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","description":"`ss -s` — aggregate counts: TCP/UDP/raw/frag, timewait, by state. Cheaper than the per-connection enumeration. Use as a one-shot \"are we close to a port-tuple exhaustion?\" check.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Socket summary","args":{}}],"search_terms":[],"command":{"binary":"ss","argv":["-s"]}},{"id":"debugging.swap_status","title":"Swap usage summary","summary":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","description":"`swapon --show` plus the per-process swap usage (top 20). Read-only. Use to spot a host actively swapping — swap-in I/O is the slowest userland-visible memory tier.","kind":"exec","risk":"low","side_effects":["One swapon invocation + a /proc scan.","Read-only."],"args":[],"examples":[{"title":"Swap usage + top swappers","args":{}}],"search_terms":["thrashing"],"command":{"binary":"/bin/sh","argv":["-c","swapon --show; echo; cat /proc/swaps; echo; for f in /proc/[0-9]*/status; do awk '/VmSwap|Name/{printf \"%s %s \",$2,$3}END{print \"\"}' \"$f\" 2>/dev/null; done | sort -k 2 -n -r | head -20"]}},{"id":"debugging.sysctl_set","title":"sysctl -w <key>=<value>","summary":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","description":"Change a runtime kernel parameter. Change is not persistent — reverts at next boot unless mirrored in /etc/sysctl.d/. Wrong values can crash the kernel (net.* tunables especially). Read the current value first.","kind":"exec","risk":"high","side_effects":["Kernel tunable updated for current boot.","Effect varies — net buffers, vm overcommit, kernel.panic, etc.","Not persistent across reboot."],"args":[{"name":"key","type":"string","required":true,"description":"sysctl key (e.g., net.ipv4.tcp_max_syn_backlog).","validation":{"pattern":"^[a-z0-9][a-z0-9._\\-]{0,127}$"}},{"name":"value","type":"string","required":true,"description":"New value.","validation":{"pattern":"^[a-zA-Z0-9_:.,\\-/= ]{1,256}$"}}],"examples":[{"title":"Raise SYN backlog","args":{"key":"net.ipv4.tcp_max_syn_backlog","value":"4096"}}],"search_terms":[],"command":{"binary":"sysctl","argv":["-w","{{ args.key }}={{ args.value }}"]}},{"id":"debugging.tcp_retrans_top","title":"TCP connections with retransmits","summary":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","description":"`ss -i state established` filtered to flows showing retrans counters. Use when network latency is high — surfaces which peers are seeing TCP loss without a tcpdump. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"Top retransmitting flows","args":{}}],"search_terms":["retransmissions","packet loss"],"command":{"binary":"/bin/sh","argv":["-c","ss -tnpi state established | awk '/retrans/{print}' | sort -k 5 | head -50"]}},{"id":"debugging.tcp_summary","title":"TCP state counts","summary":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","description":"Return the count of TCP sockets in each state (ESTAB, TIME-WAIT, CLOSE-WAIT, FIN-WAIT-*, SYN-*). High CLOSE-WAIT usually means the application isn't close()ing; high TIME-WAIT means short-lived client connections. Read-only.","kind":"exec","risk":"low","side_effects":["One ss invocation.","Read-only."],"args":[],"examples":[{"title":"TCP states at a glance","args":{}}],"search_terms":["connection flood","syn flood","too many connections"],"command":{"binary":"/bin/sh","argv":["-c","ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr"]}},{"id":"debugging.top_open_files","title":"Top processes by open-file count","summary":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","description":"Aggregate `lsof` by PID and return the top 20 PIDs holding the most file descriptors. Use to find FD-leak candidates before EMFILE breaks something. Unless the runner runs as root it sees only its own user's processes, so the ranking is scoped to those. Read-only.","kind":"exec","risk":"low","side_effects":["One lsof invocation.","Read-only; may be slow on large systems."],"args":[],"examples":[{"title":"Top 20 PIDs by FD count","args":{}}],"search_terms":["too many open files"],"command":{"binary":"/bin/sh","argv":["-c","lsof -F p 2>/dev/null | sort | uniq -c | sort -rn | head -20\nexit ${PIPESTATUS:-0}\n"]}},{"id":"debugging.vmstat","title":"vmstat sample","summary":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","description":"Run `vmstat 1 N` to capture N one-second samples. Shows run/block queues, free memory, swap pressure, context switches, and per-CPU user/system/iowait. Use to spot a CPU-bound vs IO-bound vs context-switch-storm problem.","kind":"exec","risk":"low","side_effects":["One vmstat invocation lasting N seconds.","Read-only."],"args":[{"name":"samples","type":"integer","required":false,"default":5,"description":"How many one-second samples to collect.","validation":{"min":2,"max":60}}],"examples":[{"title":"5-second snapshot","args":{}}],"search_terms":[],"command":{"binary":"vmstat","argv":["1","{{ args.samples }}"]}}]}],"retired_below":"0.2.14"},{"id":"dell-idrac","name":"Dell iDRAC (Redfish)","version":"0.2.6","description":"Monitor and operate a Dell iDRAC over its Redfish REST API with curl — system identity and health rollup, the Dell subsystem rollup, storage controllers and drives, power and thermal telemetry, firmware inventory, the System Event Log and Lifecycle Controller log, and the Lifecycle Controller job queue. Plus gated mutators: power control (ComputerSystem.Reset), clear / delete a job, and clear the SEL. Targets an iDRAC by hostname/IP; credentials come from the runner environment. Reads are read-only GETs.","vendor":"emisar","homepage":"https://emisar.dev/packs/dell-idrac","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/dell-idrac","content_hash":"sha256:22cc9614c549892202e8de8daceafe00dbd14e44bee1f32ae2d042f02b72751a","tarball_url":"https://registry.emisar.dev/v1/packs/dell-idrac/0.2.6/22cc9614c549892202e8de8daceafe00dbd14e44bee1f32ae2d042f02b72751a/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Every action calls the iDRAC Redfish API at https://{{ args.host }}/redfish via curl on the runner host. The target must be listed exactly in `IDRAC_ALLOWED_HOSTS`. Auth is HTTP Basic from `IDRAC_USER` and `IDRAC_PASSWORD` (sent as an Authorization header over curl stdin, never in argv or the audit log).","env":[{"name":"IDRAC_ALLOWED_HOSTS","required":true,"description":"Comma-separated exact iDRAC hostnames or IPv4 addresses that actions may target. Hostname matching is ASCII case-insensitive; entries do not accept wildcards, CIDRs, URLs, or spaces.","example":"idrac-web01.mgmt,10.20.0.15"},{"name":"IDRAC_USER","required":true,"description":"iDRAC account name. Provision a dedicated least-privilege account: a read-only role covers every read; the job and reset mutators need an Operator/ConfigureComponents role.","example":"monitor"},{"name":"IDRAC_PASSWORD","required":true,"description":"iDRAC account password. Sent as an HTTP Basic Authorization header piped to curl over stdin, so it never lands in argv, a `ps` listing, or the audit log."},{"name":"IDRAC_INSECURE","description":"Set to exactly \"true\" to skip TLS verification of the iDRAC certificate. Unset (and any other value) verifies — the secure default, since credentials travel over this channel. iDRAC ships a Dell self-signed cert, so either install a CA-signed cert on the iDRAC (preferred) or set this escape hatch explicitly for a self-signed fleet.","example":"true"}],"notes":["Create the account in the iDRAC web UI under iDRAC Settings → Users → Local Users: take a free slot, enable it, and give it the Read Only role for the reads or Operator for the job and reset mutators.","`IDRAC_ALLOWED_HOSTS`, `IDRAC_USER`, `IDRAC_PASSWORD`, and any `IDRAC_INSECURE` override must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so a variable present on the host but not inherited is silently dropped and the call is refused or fails to authenticate.","Auth is HTTP Basic on purpose. It consumes no iDRAC session slot, whereas X-Auth-Token sessions draw from the shared web/Redfish session budget (iDRAC9: 8 concurrent, iDRAC8: 6); monitoring tools that open sessions and never close them are the classic cause of a 'maximum number of user sessions reached' lockout of the GUI/admin. Stateless Basic polls avoid that entirely.","Redfish API access (health, power/thermal, SEL/LC logs, firmware inventory, job queue, power control) is available at the iDRAC Basic license tier — this pack needs no Enterprise/Datacenter license. Streaming telemetry (SSE) would; plain polling does not.","Resource IDs are the stable embedded primaries System.Embedded.1 (system/chassis) and iDRAC.Embedded.1 (manager), unchanged across iDRAC8 and iDRAC9. The power/thermal reads use the universal /Power and /Thermal resources; newer firmware also exposes /PowerSubsystem, /ThermalSubsystem, and /Sensors, reachable via the generic get action."],"verify":"idrac.system"},"actions":[{"id":"idrac.clear_job_queue","title":"Clear the Lifecycle Controller job queue","summary":"Clear the iDRAC job queue — POST /redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/DellJobService/Actions/DellJobService.DeleteJobQueue. JID_CLEARALL deletes all scheduled jobs and the pending attribute values attached to them; JID_CLEARALL_FORCE additionally restarts the Lifecycle Controller services — a last resort when the iDRAC/LC is wedged. Use to unstick a queue that is blocking new config or firmware jobs. Inspect the queue with jobs first; this can cancel work that is mid-flight.","description":"Clear the iDRAC job queue — POST /redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/DellJobService/Actions/DellJobService.DeleteJobQueue. JID_CLEARALL deletes all scheduled jobs and the pending attribute values attached to them; JID_CLEARALL_FORCE additionally restarts the Lifecycle Controller services — a last resort when the iDRAC/LC is wedged. Use to unstick a queue that is blocking new config or firmware jobs. Inspect the queue with jobs first; this can cancel work that is mid-flight.","kind":"script","risk":"high","side_effects":["JID_CLEARALL: deletes every scheduled job and discards the pending configuration values staged with them.","JID_CLEARALL_FORCE: the above, plus restarts the Lifecycle Controller services (brief LC unavailability).","Can cancel an in-progress configuration or firmware-update job; pending changes are lost, not applied.","Does not change the server's power state or running OS."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"scope","type":"string","required":false,"default":"JID_CLEARALL","description":"JID_CLEARALL clears all scheduled jobs; JID_CLEARALL_FORCE also restarts the LC services (last resort).","validation":{"enum":["JID_CLEARALL","JID_CLEARALL_FORCE"]}}],"examples":[{"title":"Clear all scheduled jobs","args":{"host":"idrac-web01.mgmt"}},{"title":"Force-clear and restart LC services (wedged iDRAC)","args":{"host":"idrac-web01.mgmt","scope":"JID_CLEARALL_FORCE"}}],"search_terms":[]},{"id":"idrac.clear_sel","title":"Clear the System Event Log","summary":"Erase the iDRAC System Event Log — POST /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Actions/LogService.ClearLog. IRREVERSIBLE: every SEL entry is wiped and cannot be recovered. Pull the log with sel first if you need a record. Routine after addressing the faults a server logged, but it destroys forensic history, so it is gated. (The Lifecycle Controller log is append-only and is intentionally not clearable here.)","description":"Erase the iDRAC System Event Log — POST /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Actions/LogService.ClearLog. IRREVERSIBLE: every SEL entry is wiped and cannot be recovered. Pull the log with sel first if you need a record. Routine after addressing the faults a server logged, but it destroys forensic history, so it is gated. (The Lifecycle Controller log is append-only and is intentionally not clearable here.)","kind":"script","risk":"high","side_effects":["Irreversibly erases ALL System Event Log entries on the iDRAC.","Cannot be undone; prior hardware-fault history is lost.","Does not affect the Lifecycle Controller log, the running OS, or power state."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Clear the SEL after addressing faults","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.delete_job","title":"Delete one Lifecycle Controller job","summary":"Delete a single job from the queue by id — DELETE /redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_xxxxxxxxxxxx. The surgical alternative to clear_job_queue: remove one stuck or unwanted job (find its JID with jobs) without touching the rest of the queue. Deleting a scheduled job discards its pending change; it does not undo a job that already completed.","description":"Delete a single job from the queue by id — DELETE /redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_xxxxxxxxxxxx. The surgical alternative to clear_job_queue: remove one stuck or unwanted job (find its JID with jobs) without touching the rest of the queue. Deleting a scheduled job discards its pending change; it does not undo a job that already completed.","kind":"script","risk":"medium","side_effects":["Deletes the one named job from the iDRAC job queue.","If the job was scheduled (not yet applied), its pending change is discarded.","Leaves all other jobs and the server's power state untouched."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"job_id","type":"string","required":true,"description":"The job id to delete (JID_ followed by digits), as shown by jobs.","validation":{"pattern":"^JID_[A-Za-z0-9]{1,40}$","max_length":44}}],"examples":[{"title":"Delete a stuck job by id","args":{"host":"idrac-web01.mgmt","job_id":"JID_123456789012"}}],"search_terms":[]},{"id":"idrac.firmware","title":"List installed firmware versions","summary":"List the firmware inventory — GET /redfish/v1/UpdateService/FirmwareInventory?$expand=*($levels=1). Returns one member per component (BIOS, iDRAC, NIC, PERC, PSU, drives, …) with its Version and whether it is Updateable. Members are prefixed Installed- (running), Available- (staged/pending), or Previous- (rollback image). The answer to \"what firmware is on this box and is anything pending?\".","description":"List the firmware inventory — GET /redfish/v1/UpdateService/FirmwareInventory?$expand=*($levels=1). Returns one member per component (BIOS, iDRAC, NIC, PERC, PSU, drives, …) with its Version and whether it is Updateable. Members are prefixed Installed- (running), Available- (staged/pending), or Previous- (rollback image). The answer to \"what firmware is on this box and is anything pending?\".","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the firmware inventory, expanded one level.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"All installed firmware versions","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.get","title":"GET an arbitrary Redfish resource","summary":"Get any Redfish resource by path — a read-only GET under /redfish/v1 that the curated reads do not cover. Give a path like /Chassis/System.Embedded.1/Sensors or /Systems/System.Embedded.1/Memory?$expand=*($levels=1), including a query string ($expand, $skip, $filter). Use it to reach newer subsystems (/PowerSubsystem, /ThermalSubsystem), page a long log (?$skip=50), or read a single job (/Managers/iDRAC.Embedded.1/Jobs/JID_xx…). Read-only — it only ever issues a GET.","description":"Get any Redfish resource by path — a read-only GET under /redfish/v1 that the curated reads do not cover. Give a path like /Chassis/System.Embedded.1/Sensors or /Systems/System.Embedded.1/Memory?$expand=*($levels=1), including a query string ($expand, $skip, $filter). Use it to reach newer subsystems (/PowerSubsystem, /ThermalSubsystem), page a long log (?$skip=50), or read a single job (/Managers/iDRAC.Embedded.1/Jobs/JID_xx…). Read-only — it only ever issues a GET.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the supplied path.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"path","type":"string","required":true,"description":"Resource path under /redfish/v1, starting with /. May include a query string; URL-encode any spaces (e.g. %20 inside a $filter).","validation":{"pattern":"^/[A-Za-z0-9._~:/?$()*,=&%@'+-]{1,256}$","max_length":256}}],"examples":[{"title":"Read the flat Sensors collection (newer firmware)","args":{"host":"idrac-web01.mgmt","path":"/Chassis/System.Embedded.1/Sensors?$expand=*($levels=1)"}},{"title":"Page the SEL past the first 50 entries","args":{"host":"idrac-web01.mgmt","path":"/Managers/iDRAC.Embedded.1/LogServices/Sel/Entries?$skip=50"}}],"search_terms":[]},{"id":"idrac.health","title":"Show per-subsystem health rollup","summary":"Show the Dell subsystem health rollup in one call — GET /redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRollupStatus. Returns a member per subsystem (Processor, Memory, Storage, Fan, PowerSupply, Voltage, Intrusion, …), each with a SubSystem name and its RollupStatus (Ok / Warning / Critical), so one read tells you exactly which subsystem is degraded. The fastest \"what is unhealthy on this box?\" answer.","description":"Show the Dell subsystem health rollup in one call — GET /redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRollupStatus. Returns a member per subsystem (Processor, Memory, Storage, Fan, PowerSupply, Voltage, Intrusion, …), each with a SubSystem name and its RollupStatus (Ok / Warning / Critical), so one read tells you exactly which subsystem is degraded. The fastest \"what is unhealthy on this box?\" answer.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Dell rollup-status collection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Which subsystem is unhealthy?","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.jobs","title":"List Lifecycle Controller jobs","summary":"List the Lifecycle Controller job queue — GET /redfish/v1/Managers/iDRAC.Embedded.1/Jobs?$expand=*($levels=1). Each job is expanded inline with its Id (JID_...), JobState (Scheduled / Running / Completed / Failed), PercentComplete, and Message. The answer to \"what config/firmware jobs are queued or running, and how far along?\". A queued job shows JobState Scheduled — read PercentComplete for true progress. Read-only.","description":"List the Lifecycle Controller job queue — GET /redfish/v1/Managers/iDRAC.Embedded.1/Jobs?$expand=*($levels=1). Each job is expanded inline with its Id (JID_...), JobState (Scheduled / Running / Completed / Failed), PercentComplete, and Message. The answer to \"what config/firmware jobs are queued or running, and how far along?\". A queued job shows JobState Scheduled — read PercentComplete for true progress. Read-only.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the iDRAC job collection, expanded one level.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"All jobs with state and progress","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.lclog","title":"List Lifecycle Controller log entries","summary":"List the Lifecycle Controller log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Lclog/Entries. The LC log is the iDRAC's own activity history: configuration changes, firmware updates, job results, and component events, each with Created, Severity, MessageId, and Message. Broader than the SEL (which is hardware faults only). Read-only.","description":"List the Lifecycle Controller log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Lclog/Entries. The LC log is the iDRAC's own activity history: configuration changes, firmware updates, job results, and component events, each with Created, Severity, MessageId, and Message. Broader than the SEL (which is hardware faults only). Read-only.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Lifecycle Controller log entries.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Lifecycle Controller log","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.manager","title":"Show iDRAC manager state and firmware","summary":"Show the iDRAC controller itself — GET /redfish/v1/Managers/iDRAC.Embedded.1. Returns the iDRAC firmware version, model, date/time, and its own Status.Health. Use to confirm the management controller's firmware level and that the iDRAC is healthy, as distinct from the server it manages.","description":"Show the iDRAC controller itself — GET /redfish/v1/Managers/iDRAC.Embedded.1. Returns the iDRAC firmware version, model, date/time, and its own Status.Health. Use to confirm the management controller's firmware level and that the iDRAC is healthy, as distinct from the server it manages.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Manager resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"iDRAC firmware and health","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.power","title":"Show power supplies and consumption","summary":"Show power telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Power. Returns each power supply (model, capacity, line input, Status.Health) and their redundancy, the system voltages, and the current/average power consumed in watts. Use to check PSU health/redundancy and draw. (Newer iDRAC firmware also serves /PowerSubsystem; this universal /Power resource works on iDRAC8 and iDRAC9.)","description":"Show power telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Power. Returns each power supply (model, capacity, line input, Status.Health) and their redundancy, the system voltages, and the current/average power consumed in watts. Use to check PSU health/redundancy and draw. (Newer iDRAC firmware also serves /PowerSubsystem; this universal /Power resource works on iDRAC8 and iDRAC9.)","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Power resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"PSU health and power draw","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.power_control","title":"Reset / power-control the server","summary":"Change the server's power state via Redfish — POST /redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset with the chosen ResetType.","description":"Change the server's power state via Redfish — POST /redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset with the chosen ResetType. GracefulShutdown and GracefulRestart ask the OS to stop cleanly; ForceOff, ForceRestart, PowerCycle, and Nmi are abrupt and can lose in-flight data. On (power up) and PushPowerButton (toggle) are also available. Check the current state with system (PowerState) first. The exact ResetType set varies by iDRAC firmware — the iDRAC rejects an unsupported value with an error.","kind":"script","risk":"critical","side_effects":["GracefulShutdown / GracefulRestart: asks the OS to shut down or reboot in an orderly way (the OS may delay or refuse).","ForceOff / ForceRestart / PowerCycle: abrupt power-off / reset with no OS coordination — unsaved data can be lost.","Nmi: sends a non-maskable interrupt (triggers a crash/diagnostic dump), not a clean power action.","On / PushPowerButton: powers up / toggles the virtual power button.","Any restart or off drops every running service and open connection on the host."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"reset_type","type":"string","required":true,"description":"Redfish ResetType. Graceful: GracefulShutdown, GracefulRestart. Forceful: ForceOff, ForceRestart, PowerCycle, Nmi. Power up: On, PushPowerButton.","validation":{"enum":["On","GracefulShutdown","GracefulRestart","ForceRestart","ForceOff","PowerCycle","PushPowerButton","Nmi"]}}],"examples":[{"title":"Graceful restart","args":{"host":"idrac-web01.mgmt","reset_type":"GracefulRestart"}},{"title":"Hard power-off an unresponsive host","args":{"host":"idrac-web01.mgmt","reset_type":"ForceOff"}}],"search_terms":[]},{"id":"idrac.sel","title":"List System Event Log entries","summary":"List the System Event Log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Entries. Each entry has Created, Severity (OK / Warning / Critical), Message, MessageId, and the sensor that raised it — the hardware-fault history (ECC, PSU, thermal, intrusion). Read-only. For a long log, page with the generic get action and ?$skip=N, or filter with ?$filter=Severity eq 'Critical'.","description":"List the System Event Log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Entries. Each entry has Created, Severity (OK / Warning / Critical), Message, MessageId, and the sensor that raised it — the hardware-fault history (ECC, PSU, thermal, intrusion). Read-only. For a long log, page with the generic get action and ?$skip=N, or filter with ?$filter=Severity eq 'Critical'.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the SEL entries collection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"System Event Log","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.storage","title":"Show storage controllers and drives","summary":"List the storage subsystem with controllers and drives expanded in one call — GET /redfish/v1/Systems/System.Embedded.1/Storage?$expand=*($levels=1). Returns each controller (e.g. PERC) and its physical drives with capacity, media type, and Status.Health, so you can spot a predicted or failed drive. Read-only.","description":"List the storage subsystem with controllers and drives expanded in one call — GET /redfish/v1/Systems/System.Embedded.1/Storage?$expand=*($levels=1). Returns each controller (e.g. PERC) and its physical drives with capacity, media type, and Status.Health, so you can spot a predicted or failed drive. Read-only.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Storage collection, expanded one level.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Controllers and drive health","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.system","title":"Show system identity, power state, health","summary":"Show the server's top-line state — GET /redfish/v1/Systems/System.Embedded.1. Returns model, service tag (SKU), BIOS version, PowerState (On/Off), the overall Status.HealthRollup (OK / Warning / Critical, aggregating subordinate subsystems), and the inline ProcessorSummary and MemorySummary health. The starting point for \"what is this server and is it healthy?\", and the action to verify the pack can reach and authenticate to an iDRAC.","description":"Show the server's top-line state — GET /redfish/v1/Systems/System.Embedded.1. Returns model, service tag (SKU), BIOS version, PowerState (On/Off), the overall Status.HealthRollup (OK / Warning / Critical, aggregating subordinate subsystems), and the inline ProcessorSummary and MemorySummary health. The starting point for \"what is this server and is it healthy?\", and the action to verify the pack can reach and authenticate to an iDRAC.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the ComputerSystem resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"System identity and health","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.thermal","title":"Show fans and temperatures","summary":"Show thermal telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Thermal. Returns each temperature sensor (inlet, exhaust, CPU) in Celsius with its thresholds and each fan's RPM and Status.Health, plus fan redundancy. Use to check for a hot inlet, a failed fan, or lost cooling redundancy. (Newer iDRAC firmware also serves /ThermalSubsystem; this universal /Thermal resource works on iDRAC8 and iDRAC9.)","description":"Show thermal telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Thermal. Returns each temperature sensor (inlet, exhaust, CPU) in Celsius with its thresholds and each fan's RPM and Status.Health, plus fan redundancy. Use to check for a hot inlet, a failed fan, or lost cooling redundancy. (Newer iDRAC firmware also serves /ThermalSubsystem; this universal /Thermal resource works on iDRAC8 and iDRAC9.)","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Thermal resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Fans and temperatures","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]}],"previous_versions":[{"version":"0.2.5","content_hash":"sha256:77bf347e730d904f624b87a802384354c4a53e605ebecfa324a566fabef12c70","tarball_url":"https://registry.emisar.dev/v1/packs/dell-idrac/0.2.5/77bf347e730d904f624b87a802384354c4a53e605ebecfa324a566fabef12c70/pack.tar.gz","actions":[{"id":"idrac.clear_job_queue","title":"Clear the Lifecycle Controller job queue","summary":"Clear the iDRAC job queue — POST /redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/DellJobService/Actions/DellJobService.DeleteJobQueue. JID_CLEARALL deletes all scheduled jobs and the pending attribute values attached to them; JID_CLEARALL_FORCE additionally restarts the Lifecycle Controller services — a last resort when the iDRAC/LC is wedged. Use to unstick a queue that is blocking new config or firmware jobs. Inspect the queue with jobs first; this can cancel work that is mid-flight.","description":"Clear the iDRAC job queue — POST /redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/DellJobService/Actions/DellJobService.DeleteJobQueue. JID_CLEARALL deletes all scheduled jobs and the pending attribute values attached to them; JID_CLEARALL_FORCE additionally restarts the Lifecycle Controller services — a last resort when the iDRAC/LC is wedged. Use to unstick a queue that is blocking new config or firmware jobs. Inspect the queue with jobs first; this can cancel work that is mid-flight.","kind":"script","risk":"high","side_effects":["JID_CLEARALL: deletes every scheduled job and discards the pending configuration values staged with them.","JID_CLEARALL_FORCE: the above, plus restarts the Lifecycle Controller services (brief LC unavailability).","Can cancel an in-progress configuration or firmware-update job; pending changes are lost, not applied.","Does not change the server's power state or running OS."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"scope","type":"string","required":false,"default":"JID_CLEARALL","description":"JID_CLEARALL clears all scheduled jobs; JID_CLEARALL_FORCE also restarts the LC services (last resort).","validation":{"enum":["JID_CLEARALL","JID_CLEARALL_FORCE"]}}],"examples":[{"title":"Clear all scheduled jobs","args":{"host":"idrac-web01.mgmt"}},{"title":"Force-clear and restart LC services (wedged iDRAC)","args":{"host":"idrac-web01.mgmt","scope":"JID_CLEARALL_FORCE"}}],"search_terms":[]},{"id":"idrac.clear_sel","title":"Clear the System Event Log","summary":"Erase the iDRAC System Event Log — POST /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Actions/LogService.ClearLog. IRREVERSIBLE: every SEL entry is wiped and cannot be recovered. Pull the log with sel first if you need a record. Routine after addressing the faults a server logged, but it destroys forensic history, so it is gated. (The Lifecycle Controller log is append-only and is intentionally not clearable here.)","description":"Erase the iDRAC System Event Log — POST /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Actions/LogService.ClearLog. IRREVERSIBLE: every SEL entry is wiped and cannot be recovered. Pull the log with sel first if you need a record. Routine after addressing the faults a server logged, but it destroys forensic history, so it is gated. (The Lifecycle Controller log is append-only and is intentionally not clearable here.)","kind":"script","risk":"high","side_effects":["Irreversibly erases ALL System Event Log entries on the iDRAC.","Cannot be undone; prior hardware-fault history is lost.","Does not affect the Lifecycle Controller log, the running OS, or power state."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Clear the SEL after addressing faults","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.delete_job","title":"Delete one Lifecycle Controller job","summary":"Delete a single job from the queue by id — DELETE /redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_xxxxxxxxxxxx. The surgical alternative to clear_job_queue: remove one stuck or unwanted job (find its JID with jobs) without touching the rest of the queue. Deleting a scheduled job discards its pending change; it does not undo a job that already completed.","description":"Delete a single job from the queue by id — DELETE /redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_xxxxxxxxxxxx. The surgical alternative to clear_job_queue: remove one stuck or unwanted job (find its JID with jobs) without touching the rest of the queue. Deleting a scheduled job discards its pending change; it does not undo a job that already completed.","kind":"script","risk":"medium","side_effects":["Deletes the one named job from the iDRAC job queue.","If the job was scheduled (not yet applied), its pending change is discarded.","Leaves all other jobs and the server's power state untouched."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"job_id","type":"string","required":true,"description":"The job id to delete (JID_ followed by digits), as shown by jobs.","validation":{"pattern":"^JID_[A-Za-z0-9]{1,40}$","max_length":44}}],"examples":[{"title":"Delete a stuck job by id","args":{"host":"idrac-web01.mgmt","job_id":"JID_123456789012"}}],"search_terms":[]},{"id":"idrac.firmware","title":"List installed firmware versions","summary":"List the firmware inventory — GET /redfish/v1/UpdateService/FirmwareInventory?$expand=*($levels=1). Returns one member per component (BIOS, iDRAC, NIC, PERC, PSU, drives, …) with its Version and whether it is Updateable. Members are prefixed Installed- (running), Available- (staged/pending), or Previous- (rollback image). The answer to \"what firmware is on this box and is anything pending?\".","description":"List the firmware inventory — GET /redfish/v1/UpdateService/FirmwareInventory?$expand=*($levels=1). Returns one member per component (BIOS, iDRAC, NIC, PERC, PSU, drives, …) with its Version and whether it is Updateable. Members are prefixed Installed- (running), Available- (staged/pending), or Previous- (rollback image). The answer to \"what firmware is on this box and is anything pending?\".","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the firmware inventory, expanded one level.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"All installed firmware versions","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.get","title":"GET an arbitrary Redfish resource","summary":"Get any Redfish resource by path — a read-only GET under /redfish/v1 that the curated reads do not cover. Give a path like /Chassis/System.Embedded.1/Sensors or /Systems/System.Embedded.1/Memory?$expand=*($levels=1), including a query string ($expand, $skip, $filter). Use it to reach newer subsystems (/PowerSubsystem, /ThermalSubsystem), page a long log (?$skip=50), or read a single job (/Managers/iDRAC.Embedded.1/Jobs/JID_xx…). Read-only — it only ever issues a GET.","description":"Get any Redfish resource by path — a read-only GET under /redfish/v1 that the curated reads do not cover. Give a path like /Chassis/System.Embedded.1/Sensors or /Systems/System.Embedded.1/Memory?$expand=*($levels=1), including a query string ($expand, $skip, $filter). Use it to reach newer subsystems (/PowerSubsystem, /ThermalSubsystem), page a long log (?$skip=50), or read a single job (/Managers/iDRAC.Embedded.1/Jobs/JID_xx…). Read-only — it only ever issues a GET.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the supplied path.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"path","type":"string","required":true,"description":"Resource path under /redfish/v1, starting with /. May include a query string; URL-encode any spaces (e.g. %20 inside a $filter).","validation":{"pattern":"^/[A-Za-z0-9._~:/?$()*,=&%@'+-]{1,256}$","max_length":256}}],"examples":[{"title":"Read the flat Sensors collection (newer firmware)","args":{"host":"idrac-web01.mgmt","path":"/Chassis/System.Embedded.1/Sensors?$expand=*($levels=1)"}},{"title":"Page the SEL past the first 50 entries","args":{"host":"idrac-web01.mgmt","path":"/Managers/iDRAC.Embedded.1/LogServices/Sel/Entries?$skip=50"}}],"search_terms":[]},{"id":"idrac.health","title":"Show per-subsystem health rollup","summary":"Show the Dell subsystem health rollup in one call — GET /redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRollupStatus. Returns a member per subsystem (Processor, Memory, Storage, Fan, PowerSupply, Voltage, Intrusion, …), each with a SubSystem name and its RollupStatus (Ok / Warning / Critical), so one read tells you exactly which subsystem is degraded. The fastest \"what is unhealthy on this box?\" answer.","description":"Show the Dell subsystem health rollup in one call — GET /redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRollupStatus. Returns a member per subsystem (Processor, Memory, Storage, Fan, PowerSupply, Voltage, Intrusion, …), each with a SubSystem name and its RollupStatus (Ok / Warning / Critical), so one read tells you exactly which subsystem is degraded. The fastest \"what is unhealthy on this box?\" answer.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Dell rollup-status collection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Which subsystem is unhealthy?","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.jobs","title":"List Lifecycle Controller jobs","summary":"List the Lifecycle Controller job queue — GET /redfish/v1/Managers/iDRAC.Embedded.1/Jobs?$expand=*($levels=1). Each job is expanded inline with its Id (JID_...), JobState (Scheduled / Running / Completed / Failed), PercentComplete, and Message. The answer to \"what config/firmware jobs are queued or running, and how far along?\". A queued job shows JobState Scheduled — read PercentComplete for true progress. Read-only.","description":"List the Lifecycle Controller job queue — GET /redfish/v1/Managers/iDRAC.Embedded.1/Jobs?$expand=*($levels=1). Each job is expanded inline with its Id (JID_...), JobState (Scheduled / Running / Completed / Failed), PercentComplete, and Message. The answer to \"what config/firmware jobs are queued or running, and how far along?\". A queued job shows JobState Scheduled — read PercentComplete for true progress. Read-only.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the iDRAC job collection, expanded one level.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"All jobs with state and progress","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.lclog","title":"List Lifecycle Controller log entries","summary":"List the Lifecycle Controller log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Lclog/Entries. The LC log is the iDRAC's own activity history: configuration changes, firmware updates, job results, and component events, each with Created, Severity, MessageId, and Message. Broader than the SEL (which is hardware faults only). Read-only.","description":"List the Lifecycle Controller log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Lclog/Entries. The LC log is the iDRAC's own activity history: configuration changes, firmware updates, job results, and component events, each with Created, Severity, MessageId, and Message. Broader than the SEL (which is hardware faults only). Read-only.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Lifecycle Controller log entries.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Lifecycle Controller log","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.manager","title":"Show iDRAC manager state and firmware","summary":"Show the iDRAC controller itself — GET /redfish/v1/Managers/iDRAC.Embedded.1. Returns the iDRAC firmware version, model, date/time, and its own Status.Health. Use to confirm the management controller's firmware level and that the iDRAC is healthy, as distinct from the server it manages.","description":"Show the iDRAC controller itself — GET /redfish/v1/Managers/iDRAC.Embedded.1. Returns the iDRAC firmware version, model, date/time, and its own Status.Health. Use to confirm the management controller's firmware level and that the iDRAC is healthy, as distinct from the server it manages.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Manager resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"iDRAC firmware and health","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.power","title":"Show power supplies and consumption","summary":"Show power telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Power. Returns each power supply (model, capacity, line input, Status.Health) and their redundancy, the system voltages, and the current/average power consumed in watts. Use to check PSU health/redundancy and draw. (Newer iDRAC firmware also serves /PowerSubsystem; this universal /Power resource works on iDRAC8 and iDRAC9.)","description":"Show power telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Power. Returns each power supply (model, capacity, line input, Status.Health) and their redundancy, the system voltages, and the current/average power consumed in watts. Use to check PSU health/redundancy and draw. (Newer iDRAC firmware also serves /PowerSubsystem; this universal /Power resource works on iDRAC8 and iDRAC9.)","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Power resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"PSU health and power draw","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.power_control","title":"Reset / power-control the server","summary":"Change the server's power state via Redfish — POST /redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset with the chosen ResetType.","description":"Change the server's power state via Redfish — POST /redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset with the chosen ResetType. GracefulShutdown and GracefulRestart ask the OS to stop cleanly; ForceOff, ForceRestart, PowerCycle, and Nmi are abrupt and can lose in-flight data. On (power up) and PushPowerButton (toggle) are also available. Check the current state with system (PowerState) first. The exact ResetType set varies by iDRAC firmware — the iDRAC rejects an unsupported value with an error.","kind":"script","risk":"critical","side_effects":["GracefulShutdown / GracefulRestart: asks the OS to shut down or reboot in an orderly way (the OS may delay or refuse).","ForceOff / ForceRestart / PowerCycle: abrupt power-off / reset with no OS coordination — unsaved data can be lost.","Nmi: sends a non-maskable interrupt (triggers a crash/diagnostic dump), not a clean power action.","On / PushPowerButton: powers up / toggles the virtual power button.","Any restart or off drops every running service and open connection on the host."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"reset_type","type":"string","required":true,"description":"Redfish ResetType. Graceful: GracefulShutdown, GracefulRestart. Forceful: ForceOff, ForceRestart, PowerCycle, Nmi. Power up: On, PushPowerButton.","validation":{"enum":["On","GracefulShutdown","GracefulRestart","ForceRestart","ForceOff","PowerCycle","PushPowerButton","Nmi"]}}],"examples":[{"title":"Graceful restart","args":{"host":"idrac-web01.mgmt","reset_type":"GracefulRestart"}},{"title":"Hard power-off an unresponsive host","args":{"host":"idrac-web01.mgmt","reset_type":"ForceOff"}}],"search_terms":[]},{"id":"idrac.sel","title":"List System Event Log entries","summary":"List the System Event Log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Entries. Each entry has Created, Severity (OK / Warning / Critical), Message, MessageId, and the sensor that raised it — the hardware-fault history (ECC, PSU, thermal, intrusion). Read-only. For a long log, page with the generic get action and ?$skip=N, or filter with ?$filter=Severity eq 'Critical'.","description":"List the System Event Log — GET /redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Entries. Each entry has Created, Severity (OK / Warning / Critical), Message, MessageId, and the sensor that raised it — the hardware-fault history (ECC, PSU, thermal, intrusion). Read-only. For a long log, page with the generic get action and ?$skip=N, or filter with ?$filter=Severity eq 'Critical'.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the SEL entries collection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"System Event Log","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.storage","title":"Show storage controllers and drives","summary":"List the storage subsystem with controllers and drives expanded in one call — GET /redfish/v1/Systems/System.Embedded.1/Storage?$expand=*($levels=1). Returns each controller (e.g. PERC) and its physical drives with capacity, media type, and Status.Health, so you can spot a predicted or failed drive. Read-only.","description":"List the storage subsystem with controllers and drives expanded in one call — GET /redfish/v1/Systems/System.Embedded.1/Storage?$expand=*($levels=1). Returns each controller (e.g. PERC) and its physical drives with capacity, media type, and Status.Health, so you can spot a predicted or failed drive. Read-only.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Storage collection, expanded one level.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Controllers and drive health","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.system","title":"Show system identity, power state, health","summary":"Show the server's top-line state — GET /redfish/v1/Systems/System.Embedded.1. Returns model, service tag (SKU), BIOS version, PowerState (On/Off), the overall Status.HealthRollup (OK / Warning / Critical, aggregating subordinate subsystems), and the inline ProcessorSummary and MemorySummary health. The starting point for \"what is this server and is it healthy?\", and the action to verify the pack can reach and authenticate to an iDRAC.","description":"Show the server's top-line state — GET /redfish/v1/Systems/System.Embedded.1. Returns model, service tag (SKU), BIOS version, PowerState (On/Off), the overall Status.HealthRollup (OK / Warning / Critical, aggregating subordinate subsystems), and the inline ProcessorSummary and MemorySummary health. The starting point for \"what is this server and is it healthy?\", and the action to verify the pack can reach and authenticate to an iDRAC.","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the ComputerSystem resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"System identity and health","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]},{"id":"idrac.thermal","title":"Show fans and temperatures","summary":"Show thermal telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Thermal. Returns each temperature sensor (inlet, exhaust, CPU) in Celsius with its thresholds and each fan's RPM and Status.Health, plus fan redundancy. Use to check for a hot inlet, a failed fan, or lost cooling redundancy. (Newer iDRAC firmware also serves /ThermalSubsystem; this universal /Thermal resource works on iDRAC8 and iDRAC9.)","description":"Show thermal telemetry — GET /redfish/v1/Chassis/System.Embedded.1/Thermal. Returns each temperature sensor (inlet, exhaust, CPU) in Celsius with its thresholds and each fan's RPM and Status.Health, plus fan redundancy. Use to check for a hot inlet, a failed fan, or lost cooling redundancy. (Newer iDRAC firmware also serves /ThermalSubsystem; this universal /Thermal resource works on iDRAC8 and iDRAC9.)","kind":"script","risk":"low","side_effects":["One read-only Redfish GET of the Thermal resource.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target iDRAC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Fans and temperatures","args":{"host":"idrac-web01.mgmt"}}],"search_terms":[]}]}],"retired_below":"0.2.5"},{"id":"dell-ipmi","name":"Dell iDRAC / IPMI (ipmitool)","version":"0.1.5","description":"Out-of-band BMC monitoring and power control over IPMI 2.0 (RMCP+/lanplus) with ipmitool — sensor data records, full sensor readings with thresholds, the System Event Log (SEL) and its summary, chassis + power state, FRU inventory, BMC firmware (mc info) and self-test, LAN config, and DCMI power draw. Plus gated mutators: chassis power control, one-time boot device, and SEL clear. Targets a Dell iDRAC or any IPMI-over-LAN baseboard controller by hostname/IP; credentials come from the runner environment. Reads are read-only.","vendor":"emisar","homepage":"https://emisar.dev/packs/dell-ipmi","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/dell-ipmi","content_hash":"sha256:994ef0e18b201da5df5723e4f0f5e4fe4a92f7ce1d7f1d35c1c604f6a7107972","tarball_url":"https://registry.emisar.dev/v1/packs/dell-ipmi/0.1.5/994ef0e18b201da5df5723e4f0f5e4fe4a92f7ce1d7f1d35c1c604f6a7107972/pack.tar.gz","requires":{"os":["linux"],"binaries":["ipmitool"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Every action runs ipmitool against the {{ args.host }} BMC you pass, over an encrypted IPMI 2.0 (lanplus) session. The target must be listed exactly in `IPMI_ALLOWED_HOSTS`. The account name is read from `IPMI_USER` and the password from `IPMI_PASSWORD` (via ipmitool's -E, so it never appears in the process arguments or the audit log).","env":[{"name":"IPMI_ALLOWED_HOSTS","required":true,"description":"Comma-separated exact BMC hostnames or IPv4 addresses that actions may target. Hostname matching is ASCII case-insensitive; entries do not accept wildcards, CIDRs, URLs, or spaces.","example":"bmc-web01.mgmt,10.20.0.16"},{"name":"IPMI_USER","required":true,"description":"BMC account name (ipmitool -U). Provision a dedicated, least-privilege monitoring account; OPERATOR privilege covers every read plus chassis power control.","example":"monitor"},{"name":"IPMI_PASSWORD","required":true,"description":"BMC account password. Read by ipmitool's -E straight from the environment, so it never lands in argv, a `ps` listing, or the audit log. We never pass -P."},{"name":"IPMI_CIPHER","description":"RMCP+ cipher suite (-C). Default 3 (RAKP-HMAC-SHA1 + AES-128-CBC), the reliable Dell baseline; ipmitool's own default changed 3->17 in 1.8.19, so the pack always sets it. Suite 0 is refused (it disables wire authentication — CVE-2013-4783). Set 17 for HMAC-SHA256 if the BMC supports it.","default":"3"},{"name":"IPMI_PRIVLEVEL","description":"Requested privilege level (-L: USER, OPERATOR, or ADMINISTRATOR). Default OPERATOR — enough for every read plus chassis power control, and less than ipmitool's own ADMINISTRATOR default. Drop to USER for a read-only account.","default":"OPERATOR"}],"notes":["Create the BMC account in the iDRAC web UI under iDRAC Settings → Users → Local Users, and grant it the OPERATOR privilege `IPMI_PRIVLEVEL` defaults to. The same account needs its IPMI LAN privilege set, which is configured on that user's page.","`IPMI_ALLOWED_HOSTS`, `IPMI_USER`, `IPMI_PASSWORD`, and any `IPMI_CIPHER` / `IPMI_PRIVLEVEL` overrides must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so a variable present on the host but not inherited is silently dropped and the call is refused or fails to authenticate.","IPMI Over LAN ships DISABLED on iDRAC9. Enable it first: iDRAC web UI -> iDRAC Settings -> Connectivity -> Network -> IPMI Settings -> Enable IPMI Over LAN; or `racadm set iDRAC.IPMILan.Enable 1`. iDRAC9 is IPMI 2.0 / RMCP+ only (the legacy `lan` interface is unsupported), which is why the pack uses lanplus.","ipmitool historically exits 0 even when the session fails (bad credential, unreachable BMC, or IPMI Over LAN disabled all surface only on stderr with empty stdout). The pack's wrapper turns an empty result into a real non-zero exit so a failure is loud, not a misleading empty success.","IPMI 2.0 has unfixable protocol weaknesses (RAKP hash disclosure, CVE-2013-4786). Isolate BMCs on a dedicated management VLAN with no internet path (NSA/CISA BMC-hardening guidance), use strong unique BMC passwords, and never enable cipher suite 0."],"verify":"ipmi.chassis_status"},"actions":[{"id":"ipmi.bootdev","title":"Set next-boot device","summary":"Set the device the server boots from on its NEXT boot — `ipmitool chassis bootdev <device>`. One-time by default (the BIOS reverts to its normal boot order afterward); it does not reboot the host, so pair it with a power action. Common use: \"boot to PXE once\" to re-image, or \"bios\" to drop into setup on the next restart.","description":"Set the device the server boots from on its NEXT boot — `ipmitool chassis bootdev <device>`. One-time by default (the BIOS reverts to its normal boot order afterward); it does not reboot the host, so pair it with a power action. Common use: \"boot to PXE once\" to re-image, or \"bios\" to drop into setup on the next restart.","kind":"script","risk":"high","side_effects":["Overrides the next boot's device selection (one-time, not persistent).","Does not power-cycle the host; the override applies at the next boot.","Changes which OS/installer the next boot lands in — wrong choice can boot an unintended image."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"device","type":"string","required":true,"description":"Boot device for the next boot.","validation":{"enum":["none","pxe","disk","cdrom","bios","safe","diag","floppy"]}}],"examples":[{"title":"Boot to PXE on the next restart","args":{"device":"pxe","host":"10.0.0.10"}}],"search_terms":["pxe boot","boot to bios"]},{"id":"ipmi.chassis_status","title":"Chassis status (power, intrusion, faults)","summary":"Show the BMC chassis status — `ipmitool chassis status`. Returns System Power (on/off), Power Restore Policy and Last Power Event, plus the Chassis Intrusion, Drive Fault, and Cooling/Fan Fault flags. The fastest power + health snapshot, and the action to verify the pack can reach and authenticate to a BMC.","description":"Show the BMC chassis status — `ipmitool chassis status`. Returns System Power (on/off), Power Restore Policy and Last Power Event, plus the Chassis Intrusion, Drive Fault, and Cooling/Fan Fault flags. The fastest power + health snapshot, and the action to verify the pack can reach and authenticate to a BMC.","kind":"script","risk":"low","side_effects":["One read-only IPMI chassis-status query.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Chassis status for a BMC","args":{"host":"10.0.0.10"}}],"search_terms":["bmc power","server power state","drive fault"]},{"id":"ipmi.dcmi_power","title":"Show DCMI power reading (watts)","summary":"Show real-time power draw via DCMI — `ipmitool dcmi power reading`. Returns the instantaneous, minimum, maximum, and average power consumption in watts over the BMC's sampling period, plus the sampling timestamp. The direct answer to \"how much is this server drawing right now?\" on BMCs that support DCMI.","description":"Show real-time power draw via DCMI — `ipmitool dcmi power reading`. Returns the instantaneous, minimum, maximum, and average power consumption in watts over the BMC's sampling period, plus the sampling timestamp. The direct answer to \"how much is this server drawing right now?\" on BMCs that support DCMI.","kind":"script","risk":"low","side_effects":["One read-only DCMI power-statistics query.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Current power draw","args":{"host":"10.0.0.10"}}],"search_terms":["power consumption","energy usage"]},{"id":"ipmi.fru","title":"Show FRU inventory","summary":"Show field-replaceable-unit inventory — `ipmitool fru print`. Returns board and product manufacturer, name, part number, and serial for the chassis and each FRU device (PSUs appear as their own devices). The Serial fields carry the Dell service tag. Inventory and asset data; no live readings.","description":"Show field-replaceable-unit inventory — `ipmitool fru print`. Returns board and product manufacturer, name, part number, and serial for the chassis and each FRU device (PSUs appear as their own devices). The Serial fields carry the Dell service tag. Inventory and asset data; no live readings.","kind":"script","risk":"low","side_effects":["One read-only IPMI FRU inventory read.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Service tag and FRU inventory","args":{"host":"10.0.0.10"}}],"search_terms":["service tag","serial number"]},{"id":"ipmi.lan_print","title":"Show BMC LAN configuration","summary":"Show the BMC LAN channel configuration — `ipmitool lan print <channel>`. Returns the BMC IP source (static/DHCP), address, netmask, MAC, default gateway, VLAN id, and the per-cipher-suite privilege map. Useful for confirming BMC network settings and which cipher suites are enabled. The SNMP community string in this output is redacted before it leaves the host.","description":"Show the BMC LAN channel configuration — `ipmitool lan print <channel>`. Returns the BMC IP source (static/DHCP), address, netmask, MAC, default gateway, VLAN id, and the per-cipher-suite privilege map. Useful for confirming BMC network settings and which cipher suites are enabled. The SNMP community string in this output is redacted before it leaves the host.","kind":"script","risk":"low","side_effects":["One read-only IPMI LAN-configuration read.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"channel","type":"integer","required":false,"default":1,"description":"IPMI LAN channel number (Dell iDRAC IPMI LAN is channel 1).","validation":{"min":1,"max":15}}],"examples":[{"title":"BMC LAN config on channel 1","args":{"host":"10.0.0.10"}}],"search_terms":[]},{"id":"ipmi.mc_info","title":"Show BMC info (firmware, capabilities)","summary":"Show management-controller identity — `ipmitool mc info`. Returns the BMC device id, firmware revision, IPMI version, manufacturer (Dell = 674) and product ids, and the list of supported capabilities (SDR repo, SEL, FRU, chassis, …). Confirms the BMC firmware level and what it can do.","description":"Show management-controller identity — `ipmitool mc info`. Returns the BMC device id, firmware revision, IPMI version, manufacturer (Dell = 674) and product ids, and the list of supported capabilities (SDR repo, SEL, FRU, chassis, …). Confirms the BMC firmware level and what it can do.","kind":"script","risk":"low","side_effects":["One read-only IPMI management-controller info query.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"BMC firmware and capabilities","args":{"host":"10.0.0.10"}}],"search_terms":[]},{"id":"ipmi.mc_selftest","title":"Run BMC self-test","summary":"Get the BMC self-test result — `ipmitool mc selftest`. A passing controller prints \"Selftest: passed\"; a failure reports the specific fault (SDR repo empty, FRU corrupt, …). A quick \"is the management controller itself healthy?\" check. Reads the controller's own diagnostics; changes nothing.","description":"Get the BMC self-test result — `ipmitool mc selftest`. A passing controller prints \"Selftest: passed\"; a failure reports the specific fault (SDR repo empty, FRU corrupt, …). A quick \"is the management controller itself healthy?\" check. Reads the controller's own diagnostics; changes nothing.","kind":"script","risk":"low","side_effects":["One read-only IPMI controller self-test query.","Read-only — reports existing self-test state, does not reset the BMC."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"BMC self-test result","args":{"host":"10.0.0.10"}}],"search_terms":[]},{"id":"ipmi.power_control","title":"Control chassis power","summary":"Change the server's power state — `ipmitool chassis power <op>`. Only \"soft\" is graceful (it sends an ACPI shutdown the OS can act on); \"off\", \"cycle\", \"reset\", and \"diag\" are abrupt and can lose in-flight data — treat them like pulling the plug. Prefer an OS-level shutdown or the iDRAC graceful path when one is available; reach for this when the host is unresponsive. Confirm the current state with power_status first.","description":"Change the server's power state — `ipmitool chassis power <op>`. Only \"soft\" is graceful (it sends an ACPI shutdown the OS can act on); \"off\", \"cycle\", \"reset\", and \"diag\" are abrupt and can lose in-flight data — treat them like pulling the plug. Prefer an OS-level shutdown or the iDRAC graceful path when one is available; reach for this when the host is unresponsive. Confirm the current state with power_status first.","kind":"script","risk":"critical","side_effects":["on: powers the chassis up.","off: immediate hard power-down (ACPI S4/S5) — NOT an OS-coordinated shutdown; unsaved data can be lost.","soft: graceful ACPI shutdown the OS performs in an orderly way (the only graceful option; the OS may delay or veto it).","cycle: hard power-off then on.","reset: hard reset with no power-off.","diag: pulses an NMI to the CPUs (triggers a crash/diagnostic dump), not a power-state change.","All non-graceful options drop every running service and open connection at once."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"operation","type":"string","required":true,"description":"Power operation. \"soft\" is graceful (ACPI); \"off\", \"cycle\", \"reset\", and \"diag\" are abrupt. \"on\" powers up.","validation":{"enum":["on","off","soft","cycle","reset","diag"]}}],"examples":[{"title":"Graceful shutdown (ACPI)","args":{"host":"10.0.0.10","operation":"soft"}},{"title":"Hard reset an unresponsive host","args":{"host":"10.0.0.10","operation":"reset"}}],"search_terms":["power cycle","hard reset","reboot server"]},{"id":"ipmi.power_status","title":"Chassis power state (on/off)","summary":"Show whether the server is powered on or off — `ipmitool chassis power status`. Returns a single line, \"Chassis Power is on\" or \"... off\". The cheapest check before or after a power action.","description":"Show whether the server is powered on or off — `ipmitool chassis power status`. Returns a single line, \"Chassis Power is on\" or \"... off\". The cheapest check before or after a power action.","kind":"script","risk":"low","side_effects":["One read-only IPMI power-status query.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Is the server on?","args":{"host":"10.0.0.10"}}],"search_terms":["bmc power","server power state","is the server on"]},{"id":"ipmi.sdr","title":"List all sensors (SDR)","summary":"List every sensor with its current reading and state — `ipmitool sdr elist`. One row per sensor data record: name, reading, status (ok / nc / cr), plus the sensor number and entity id. Covers temperatures, fans, voltages, currents, power supplies, and discrete state sensors in a single call — the workhorse health read.","description":"List every sensor with its current reading and state — `ipmitool sdr elist`. One row per sensor data record: name, reading, status (ok / nc / cr), plus the sensor number and entity id. Covers temperatures, fans, voltages, currents, power supplies, and discrete state sensors in a single call — the workhorse health read.","kind":"script","risk":"low","side_effects":["One read-only IPMI SDR repository read.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"All sensors and states","args":{"host":"10.0.0.10"}}],"search_terms":["temperatures","fan speed","voltages"]},{"id":"ipmi.sdr_type","title":"List sensors of one type","summary":"List only the sensors of a chosen type — `ipmitool sdr type <type>`. Narrows the SDR read to Temperature, Fan, Voltage, Current, or Power Supply so you get just the readings you care about (e.g. all inlet/exhaust temps, or all PSU sensors) without scanning the full repository.","description":"List only the sensors of a chosen type — `ipmitool sdr type <type>`. Narrows the SDR read to Temperature, Fan, Voltage, Current, or Power Supply so you get just the readings you care about (e.g. all inlet/exhaust temps, or all PSU sensors) without scanning the full repository.","kind":"script","risk":"low","side_effects":["One read-only IPMI SDR read filtered by sensor type.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}},{"name":"type","type":"string","required":true,"description":"Sensor type to list.","validation":{"enum":["Temperature","Fan","Voltage","Current","Power Supply"]}}],"examples":[{"title":"All temperature sensors","args":{"host":"10.0.0.10","type":"Temperature"}},{"title":"All power-supply sensors","args":{"host":"10.0.0.10","type":"Power Supply"}}],"search_terms":["fans loud","fan speed","temperature readings"]},{"id":"ipmi.sel","title":"List System Event Log entries","summary":"List the BMC System Event Log — `ipmitool sel elist`. One row per event: record id, date/time, sensor, decoded description, and asserted/deasserted. The authoritative history of hardware faults (ECC errors, PSU loss, thermal trips, intrusion). The iDRAC SEL is bounded and circular (512-1024 entries), so a full log can be large.","description":"List the BMC System Event Log — `ipmitool sel elist`. One row per event: record id, date/time, sensor, decoded description, and asserted/deasserted. The authoritative history of hardware faults (ECC errors, PSU loss, thermal trips, intrusion). The iDRAC SEL is bounded and circular (512-1024 entries), so a full log can be large.","kind":"script","risk":"low","side_effects":["One read-only IPMI System Event Log read.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Full event log","args":{"host":"10.0.0.10"}}],"search_terms":["hardware errors","ecc errors","thermal trip"]},{"id":"ipmi.sel_clear","title":"Clear the System Event Log","summary":"Erase the BMC System Event Log — `ipmitool sel clear`. IRREVERSIBLE: every recorded hardware event is wiped and cannot be recovered. Pull the log with sel first if you need a record. Routine after addressing the faults a server logged (e.g. to reset a full SEL), but destroys forensic history, so it is gated.","description":"Erase the BMC System Event Log — `ipmitool sel clear`. IRREVERSIBLE: every recorded hardware event is wiped and cannot be recovered. Pull the log with sel first if you need a record. Routine after addressing the faults a server logged (e.g. to reset a full SEL), but destroys forensic history, so it is gated.","kind":"script","risk":"high","side_effects":["Irreversibly erases ALL System Event Log entries on the BMC.","Cannot be undone; prior hardware-fault history is lost.","Does not affect the running OS or power state."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"Clear the event log after addressing faults","args":{"host":"10.0.0.10"}}],"search_terms":[]},{"id":"ipmi.sel_info","title":"Show SEL summary (count, capacity)","summary":"Show the System Event Log summary — `ipmitool sel info`. Returns the entry count, free space, percent used, last-add and last-erase timestamps, and the overflow flag, without dumping every entry. Use it to decide whether the SEL is filling up or has new events before pulling the full log.","description":"Show the System Event Log summary — `ipmitool sel info`. Returns the entry count, free space, percent used, last-add and last-erase timestamps, and the overflow flag, without dumping every entry. Use it to decide whether the SEL is filling up or has new events before pulling the full log.","kind":"script","risk":"low","side_effects":["One read-only IPMI SEL info query.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"SEL fill level","args":{"host":"10.0.0.10"}}],"search_terms":[]},{"id":"ipmi.sensor","title":"List sensors with thresholds","summary":"List sensors with their full threshold set — `ipmitool sensor list`. Like the SDR read but wider: each row adds the lower/upper non-critical, critical, and non-recoverable thresholds alongside the reading and unit. Use when you need to see how close a reading is to tripping, not just its current state. Larger output than sdr.","description":"List sensors with their full threshold set — `ipmitool sensor list`. Like the SDR read but wider: each row adds the lower/upper non-critical, critical, and non-recoverable thresholds alongside the reading and unit. Use when you need to see how close a reading is to tripping, not just its current state. Larger output than sdr.","kind":"script","risk":"low","side_effects":["One read-only IPMI sensor read.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target BMC hostname or IP.","validation":{"pattern":"^[A-Za-z0-9._-]{1,253}$","max_length":253}}],"examples":[{"title":"All sensors with thresholds","args":{"host":"10.0.0.10"}}],"search_terms":["fans loud","fan speed","temperature readings"]}],"retired_below":"0.1.5"},{"id":"dnf-rpm","name":"RHEL/Fedora package ops","version":"0.1.12","description":"Counterpart to the `debian` pack for RHEL/CentOS/Fedora/Alma/Rocky: rpm inventory, dnf check-update, narrow install/remove actions for a single named package. Equivalent risk model to the apt counterpart.","vendor":"emisar","homepage":"https://emisar.dev/packs/dnf-rpm","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/dnf-rpm","content_hash":"sha256:7ad599ed6db836c2f53f4432a89aff19fdc4df2e7e484b070eb9256ab9373a56","tarball_url":"https://registry.emisar.dev/v1/packs/dnf-rpm/0.1.12/7ad599ed6db836c2f53f4432a89aff19fdc4df2e7e484b070eb9256ab9373a56/pack.tar.gz","requires":{"os":["linux"],"binaries":["rpm","dnf"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","notes":["Read-only inventory (rpm_qa, rpm_qi, rpm_ql, dnf_check_update, dnf_history, dnf_repolist) needs no privilege. rpm_verify needs root to hash every installed file, including root-only files."],"host_access":[{"actions":["rpm.rpm_verify","rpm.dnf_install","rpm.dnf_remove","rpm.dnf_clean_metadata","dnf.upgrade_pkg","dnf.reinstall_pkg","dnf.autoremove"],"requirement":"Verify root-only packaged files or change DNF package state as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-dnf-rpm-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Verification can read every packaged file; package actions can run maintainer scripts and change any host state."}]}],"verify":"rpm.rpm_qa"},"actions":[{"id":"dnf.autoremove","title":"dnf autoremove -y","summary":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","description":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","kind":"exec","risk":"high","side_effects":["Multiple packages removed.","Disk reclaimed.","Dependency mistakes can be ugly — review the action output."],"args":[],"examples":[{"title":"Reclaim disk","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["autoremove","-y"]}},{"id":"dnf.reinstall_pkg","title":"dnf reinstall -y <pkg>","summary":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","description":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","kind":"exec","risk":"medium","side_effects":["Package files restored from the repo.","Marked config files (rpmnoreplace) preserved.","Service may restart if scriptlets do that."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Repair a package","args":{"pkg":"httpd"}}],"search_terms":[],"command":{"binary":"dnf","argv":["reinstall","-y","{{ args.pkg }}"]}},{"id":"dnf.upgrade_pkg","title":"dnf upgrade -y <pkg>","summary":"Upgrade one named package to the latest available version; the package's service may restart mid-upgrade. Use for CVE remediation. Other packages untouched.","description":"Upgrade one named package to the latest available version; the package's service may restart mid-upgrade. Use for CVE remediation. Other packages untouched.","kind":"exec","risk":"high","side_effects":["One package upgraded.","Service backed by the package may restart (depending on the package).","System briefly inconsistent until upgrade completes."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Upgrade openssl","args":{"pkg":"openssl"}}],"search_terms":[],"command":{"binary":"dnf","argv":["upgrade","-y","{{ args.pkg }}"]}},{"id":"rpm.dnf_check_update","title":"dnf check-update","summary":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","description":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","kind":"exec","risk":"low","side_effects":["Refreshes metadata cache from configured repos.","Read-only — no install."],"args":[],"examples":[{"title":"Updates","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["check-update"]}},{"id":"rpm.dnf_clean_metadata","title":"dnf clean metadata","summary":"Wipe cached repo metadata. Next dnf call refetches.","description":"Wipe cached repo metadata. Next dnf call refetches.","kind":"exec","risk":"medium","side_effects":["Local metadata cache removed.","Next operation downloads fresh metadata (one-time slowdown)."],"args":[],"examples":[{"title":"Wipe cache","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["clean","metadata"]}},{"id":"rpm.dnf_history","title":"dnf history","summary":"List recent DNF transactions (installs / removes / updates).","description":"List recent DNF transactions (installs / removes / updates).","kind":"exec","risk":"low","side_effects":["One dnf history read.","Read-only."],"args":[],"examples":[{"title":"History","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["history"]}},{"id":"rpm.dnf_install","title":"dnf install -y <pkg>","summary":"Install one package + its dependencies; its scriptlets run as root and can restart the services it ships.","description":"Install one package + its dependencies; its scriptlets run as root and can restart the services it ships.","kind":"exec","risk":"high","side_effects":["Resolves + installs dependency tree.","May restart services declared by the package's scriptlets."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Install jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["install","-y","{{ args.package }}"]}},{"id":"rpm.dnf_remove","title":"dnf remove -y <pkg>","summary":"Remove one package + dependencies that no longer have a reverse-dep; removing a package that backs a running service takes that service down.","description":"Remove one package + dependencies that no longer have a reverse-dep; removing a package that backs a running service takes that service down.","kind":"exec","risk":"high","side_effects":["Files installed by the package are deleted.","Other packages depending on it may also be removed."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Uninstall jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["remove","-y","{{ args.package }}"]}},{"id":"rpm.dnf_repolist","title":"dnf repolist","summary":"List enabled repositories with package counts.","description":"List enabled repositories with package counts.","kind":"exec","risk":"low","side_effects":["One repo metadata read.","Read-only."],"args":[],"examples":[{"title":"Repos","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["repolist","-v"]}},{"id":"rpm.rpm_qa","title":"rpm -qa","summary":"List all installed RPMs.","description":"List all installed RPMs.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qa"]}},{"id":"rpm.rpm_qi","title":"rpm -qi <pkg>","summary":"Show details for one package — version, release, install date, signer.","description":"Show details for one package — version, release, install date, signer.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Info on httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qi","{{ args.package }}"]}},{"id":"rpm.rpm_ql","title":"rpm -ql <pkg>","summary":"List all files installed by one package.","description":"List all files installed by one package.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Files in httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-ql","{{ args.package }}"]}},{"id":"rpm.rpm_verify","title":"rpm -Va (verify all)","summary":"Verify every installed file's checksum / size / perms against the rpm. Lists only mismatches.","description":"Verify every installed file's checksum / size / perms against the rpm. Lists only mismatches.","kind":"exec","risk":"low","side_effects":["Reads every package's files for verification — IO-heavy.","Read-only."],"args":[],"examples":[{"title":"Verify all","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-Va"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:559d8a09432307b2abc9446ad84d4bf2110d953c3823f32eb34188ecdfea708d","tarball_url":"https://registry.emisar.dev/v1/packs/dnf-rpm/0.1.10/559d8a09432307b2abc9446ad84d4bf2110d953c3823f32eb34188ecdfea708d/pack.tar.gz","actions":[{"id":"dnf.autoremove","title":"dnf autoremove -y","summary":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","description":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","kind":"exec","risk":"high","side_effects":["Multiple packages removed.","Disk reclaimed.","Dependency mistakes can be ugly — review the action output."],"args":[],"examples":[{"title":"Reclaim disk","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["autoremove","-y"]}},{"id":"dnf.reinstall_pkg","title":"dnf reinstall -y <pkg>","summary":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","description":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","kind":"exec","risk":"medium","side_effects":["Package files restored from the repo.","Marked config files (rpmnoreplace) preserved.","Service may restart if scriptlets do that."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Repair a package","args":{"pkg":"httpd"}}],"search_terms":[],"command":{"binary":"dnf","argv":["reinstall","-y","{{ args.pkg }}"]}},{"id":"dnf.upgrade_pkg","title":"dnf upgrade -y <pkg>","summary":"Upgrade one named package to the latest available version; the package's service may restart mid-upgrade. Use for CVE remediation. Other packages untouched.","description":"Upgrade one named package to the latest available version; the package's service may restart mid-upgrade. Use for CVE remediation. Other packages untouched.","kind":"exec","risk":"high","side_effects":["One package upgraded.","Service backed by the package may restart (depending on the package).","System briefly inconsistent until upgrade completes."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Upgrade openssl","args":{"pkg":"openssl"}}],"search_terms":[],"command":{"binary":"dnf","argv":["upgrade","-y","{{ args.pkg }}"]}},{"id":"rpm.dnf_check_update","title":"dnf check-update","summary":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","description":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","kind":"exec","risk":"low","side_effects":["Refreshes metadata cache from configured repos.","Read-only — no install."],"args":[],"examples":[{"title":"Updates","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["check-update"]}},{"id":"rpm.dnf_clean_metadata","title":"dnf clean metadata","summary":"Wipe cached repo metadata. Next dnf call refetches.","description":"Wipe cached repo metadata. Next dnf call refetches.","kind":"exec","risk":"medium","side_effects":["Local metadata cache removed.","Next operation downloads fresh metadata (one-time slowdown)."],"args":[],"examples":[{"title":"Wipe cache","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["clean","metadata"]}},{"id":"rpm.dnf_history","title":"dnf history","summary":"List recent DNF transactions (installs / removes / updates).","description":"List recent DNF transactions (installs / removes / updates).","kind":"exec","risk":"low","side_effects":["One dnf history read.","Read-only."],"args":[],"examples":[{"title":"History","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["history"]}},{"id":"rpm.dnf_install","title":"dnf install -y <pkg>","summary":"Install one package + its dependencies; its scriptlets run as root and can restart the services it ships.","description":"Install one package + its dependencies; its scriptlets run as root and can restart the services it ships.","kind":"exec","risk":"high","side_effects":["Resolves + installs dependency tree.","May restart services declared by the package's scriptlets."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Install jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["install","-y","{{ args.package }}"]}},{"id":"rpm.dnf_remove","title":"dnf remove -y <pkg>","summary":"Remove one package + dependencies that no longer have a reverse-dep; removing a package that backs a running service takes that service down.","description":"Remove one package + dependencies that no longer have a reverse-dep; removing a package that backs a running service takes that service down.","kind":"exec","risk":"high","side_effects":["Files installed by the package are deleted.","Other packages depending on it may also be removed."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Uninstall jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["remove","-y","{{ args.package }}"]}},{"id":"rpm.dnf_repolist","title":"dnf repolist","summary":"List enabled repositories with package counts.","description":"List enabled repositories with package counts.","kind":"exec","risk":"low","side_effects":["One repo metadata read.","Read-only."],"args":[],"examples":[{"title":"Repos","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["repolist","-v"]}},{"id":"rpm.rpm_qa","title":"rpm -qa","summary":"List all installed RPMs.","description":"List all installed RPMs.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qa"]}},{"id":"rpm.rpm_qi","title":"rpm -qi <pkg>","summary":"Show details for one package — version, release, install date, signer.","description":"Show details for one package — version, release, install date, signer.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Info on httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qi","{{ args.package }}"]}},{"id":"rpm.rpm_ql","title":"rpm -ql <pkg>","summary":"List all files installed by one package.","description":"List all files installed by one package.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Files in httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-ql","{{ args.package }}"]}},{"id":"rpm.rpm_verify","title":"rpm -Va (verify all)","summary":"Verify every installed file's checksum / size / perms against the rpm. Lists only mismatches.","description":"Verify every installed file's checksum / size / perms against the rpm. Lists only mismatches.","kind":"exec","risk":"low","side_effects":["Reads every package's files for verification — IO-heavy.","Read-only."],"args":[],"examples":[{"title":"Verify all","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-Va"]}}]},{"version":"0.1.9","content_hash":"sha256:524495e91557b106311d3a40f4594e0afe964aef84b8040a825ee0bb068d53dc","tarball_url":"https://registry.emisar.dev/v1/packs/dnf-rpm/0.1.9/524495e91557b106311d3a40f4594e0afe964aef84b8040a825ee0bb068d53dc/pack.tar.gz","actions":[{"id":"dnf.autoremove","title":"dnf autoremove -y","summary":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","description":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","kind":"exec","risk":"high","side_effects":["Multiple packages removed.","Disk reclaimed.","Dependency mistakes can be ugly — review the action output."],"args":[],"examples":[{"title":"Reclaim disk","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["autoremove","-y"]}},{"id":"dnf.reinstall_pkg","title":"dnf reinstall -y <pkg>","summary":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","description":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","kind":"exec","risk":"medium","side_effects":["Package files restored from the repo.","Marked config files (rpmnoreplace) preserved.","Service may restart if scriptlets do that."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Repair a package","args":{"pkg":"httpd"}}],"search_terms":[],"command":{"binary":"dnf","argv":["reinstall","-y","{{ args.pkg }}"]}},{"id":"dnf.upgrade_pkg","title":"dnf upgrade -y <pkg>","summary":"Upgrade one named package to the latest available version; the package's service may restart mid-upgrade. Use for CVE remediation. Other packages untouched.","description":"Upgrade one named package to the latest available version; the package's service may restart mid-upgrade. Use for CVE remediation. Other packages untouched.","kind":"exec","risk":"high","side_effects":["One package upgraded.","Service backed by the package may restart (depending on the package).","System briefly inconsistent until upgrade completes."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Upgrade openssl","args":{"pkg":"openssl"}}],"search_terms":[],"command":{"binary":"dnf","argv":["upgrade","-y","{{ args.pkg }}"]}},{"id":"rpm.dnf_check_update","title":"dnf check-update","summary":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","description":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","kind":"exec","risk":"low","side_effects":["Refreshes metadata cache from configured repos.","Read-only — no install."],"args":[],"examples":[{"title":"Updates","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["check-update"]}},{"id":"rpm.dnf_clean_metadata","title":"dnf clean metadata","summary":"Wipe cached repo metadata. Next dnf call refetches.","description":"Wipe cached repo metadata. Next dnf call refetches.","kind":"exec","risk":"medium","side_effects":["Local metadata cache removed.","Next operation downloads fresh metadata (one-time slowdown)."],"args":[],"examples":[{"title":"Wipe cache","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["clean","metadata"]}},{"id":"rpm.dnf_history","title":"dnf history","summary":"List recent DNF transactions (installs / removes / updates).","description":"List recent DNF transactions (installs / removes / updates).","kind":"exec","risk":"low","side_effects":["One dnf history read.","Read-only."],"args":[],"examples":[{"title":"History","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["history"]}},{"id":"rpm.dnf_install","title":"dnf install -y <pkg>","summary":"Install one package + its dependencies; its scriptlets run as root and can restart the services it ships.","description":"Install one package + its dependencies; its scriptlets run as root and can restart the services it ships.","kind":"exec","risk":"high","side_effects":["Resolves + installs dependency tree.","May restart services declared by the package's scriptlets."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Install jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["install","-y","{{ args.package }}"]}},{"id":"rpm.dnf_remove","title":"dnf remove -y <pkg>","summary":"Remove one package + dependencies that no longer have a reverse-dep; removing a package that backs a running service takes that service down.","description":"Remove one package + dependencies that no longer have a reverse-dep; removing a package that backs a running service takes that service down.","kind":"exec","risk":"high","side_effects":["Files installed by the package are deleted.","Other packages depending on it may also be removed."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Uninstall jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["remove","-y","{{ args.package }}"]}},{"id":"rpm.dnf_repolist","title":"dnf repolist","summary":"List enabled repositories with package counts.","description":"List enabled repositories with package counts.","kind":"exec","risk":"low","side_effects":["One repo metadata read.","Read-only."],"args":[],"examples":[{"title":"Repos","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["repolist","-v"]}},{"id":"rpm.rpm_qa","title":"rpm -qa","summary":"List all installed RPMs.","description":"List all installed RPMs.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qa"]}},{"id":"rpm.rpm_qi","title":"rpm -qi <pkg>","summary":"Show details for one package — version, release, install date, signer.","description":"Show details for one package — version, release, install date, signer.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Info on httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qi","{{ args.package }}"]}},{"id":"rpm.rpm_ql","title":"rpm -ql <pkg>","summary":"List all files installed by one package.","description":"List all files installed by one package.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Files in httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-ql","{{ args.package }}"]}},{"id":"rpm.rpm_verify","title":"rpm -Va (verify all)","summary":"Verify every installed file's checksum / size / perms against the rpm. Lists only mismatches.","description":"Verify every installed file's checksum / size / perms against the rpm. Lists only mismatches.","kind":"exec","risk":"low","side_effects":["Reads every package's files for verification — IO-heavy.","Read-only."],"args":[],"examples":[{"title":"Verify all","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-Va"]}}]},{"version":"0.1.7","content_hash":"sha256:6c3d6617c7c21b60e13d7f56613baeffee1f6c014c1e21f2e419a6366aa0874f","tarball_url":"https://registry.emisar.dev/v1/packs/dnf-rpm/0.1.7/6c3d6617c7c21b60e13d7f56613baeffee1f6c014c1e21f2e419a6366aa0874f/pack.tar.gz","actions":[{"id":"dnf.autoremove","title":"dnf autoremove -y","summary":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","description":"Remove packages installed as dependencies that are no longer required by any installed package. Useful for /var/cache cleanup after a large rollback. Read the dry-run before approving (the list can be long).","kind":"exec","risk":"high","side_effects":["Multiple packages removed.","Disk reclaimed.","Dependency mistakes can be ugly — review the action output."],"args":[],"examples":[{"title":"Reclaim disk","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["autoremove","-y"]}},{"id":"dnf.reinstall_pkg","title":"dnf reinstall -y <pkg>","summary":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","description":"Reinstall one package to fix a corrupted on-disk state (missing files, bad checksums). Same version, same config.","kind":"exec","risk":"medium","side_effects":["Package files restored from the repo.","Marked config files (rpmnoreplace) preserved.","Service may restart if scriptlets do that."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Repair a package","args":{"pkg":"httpd"}}],"search_terms":[],"command":{"binary":"dnf","argv":["reinstall","-y","{{ args.pkg }}"]}},{"id":"dnf.upgrade_pkg","title":"dnf upgrade -y <pkg>","summary":"Upgrade one named package to the latest available version. Use for CVE remediation. Other packages untouched.","description":"Upgrade one named package to the latest available version. Use for CVE remediation. Other packages untouched.","kind":"exec","risk":"high","side_effects":["One package upgraded.","Service backed by the package may restart (depending on the package).","System briefly inconsistent until upgrade completes."],"args":[{"name":"pkg","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Upgrade openssl","args":{"pkg":"openssl"}}],"search_terms":[],"command":{"binary":"dnf","argv":["upgrade","-y","{{ args.pkg }}"]}},{"id":"rpm.dnf_check_update","title":"dnf check-update","summary":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","description":"List available updates. Exits 100 if updates available — non-zero IS the success signal.","kind":"exec","risk":"low","side_effects":["Refreshes metadata cache from configured repos.","Read-only — no install."],"args":[],"examples":[{"title":"Updates","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["check-update"]}},{"id":"rpm.dnf_clean_metadata","title":"dnf clean metadata","summary":"Wipes cached repo metadata. Next dnf call refetches.","description":"Wipes cached repo metadata. Next dnf call refetches.","kind":"exec","risk":"medium","side_effects":["Local metadata cache removed.","Next operation downloads fresh metadata (one-time slowdown)."],"args":[],"examples":[{"title":"Wipe cache","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["clean","metadata"]}},{"id":"rpm.dnf_history","title":"dnf history","summary":"List recent DNF transactions (installs / removes / updates).","description":"List recent DNF transactions (installs / removes / updates).","kind":"exec","risk":"low","side_effects":["One dnf history read.","Read-only."],"args":[],"examples":[{"title":"History","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["history"]}},{"id":"rpm.dnf_install","title":"dnf install -y <pkg>","summary":"Installs one package + its dependencies.","description":"Installs one package + its dependencies.","kind":"exec","risk":"high","side_effects":["Resolves + installs dependency tree.","May restart services declared by the package's scriptlets."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Install jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["install","-y","{{ args.package }}"]}},{"id":"rpm.dnf_remove","title":"dnf remove -y <pkg>","summary":"Removes one package + dependencies that no longer have a reverse-dep.","description":"Removes one package + dependencies that no longer have a reverse-dep.","kind":"exec","risk":"high","side_effects":["Files installed by the package are deleted.","Other packages depending on it may also be removed."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Uninstall jq","args":{"package":"jq"}}],"search_terms":[],"command":{"binary":"dnf","argv":["remove","-y","{{ args.package }}"]}},{"id":"rpm.dnf_repolist","title":"dnf repolist","summary":"List enabled repositories with package counts.","description":"List enabled repositories with package counts.","kind":"exec","risk":"low","side_effects":["One repo metadata read.","Read-only."],"args":[],"examples":[{"title":"Repos","args":{}}],"search_terms":[],"command":{"binary":"dnf","argv":["repolist","-v"]}},{"id":"rpm.rpm_qa","title":"rpm -qa","summary":"List all installed RPMs.","description":"List all installed RPMs.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qa"]}},{"id":"rpm.rpm_qi","title":"rpm -qi <pkg>","summary":"Show details for one package — version, release, install date, signer.","description":"Show details for one package — version, release, install date, signer.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Info on httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-qi","{{ args.package }}"]}},{"id":"rpm.rpm_ql","title":"rpm -ql <pkg>","summary":"List all files installed by one package.","description":"List all files installed by one package.","kind":"exec","risk":"low","side_effects":["One rpmdb read.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_+.\\-]{0,127}$"}}],"examples":[{"title":"Files in httpd","args":{"package":"httpd"}}],"search_terms":[],"command":{"binary":"rpm","argv":["-ql","{{ args.package }}"]}},{"id":"rpm.rpm_verify","title":"rpm -Va (verify all)","summary":"Verifies every installed file's checksum / size / perms against the rpm. Lists only mismatches.","description":"Verifies every installed file's checksum / size / perms against the rpm. Lists only mismatches.","kind":"exec","risk":"low","side_effects":["Reads every package's files for verification — IO-heavy.","Read-only."],"args":[],"examples":[{"title":"Verify all","args":{}}],"search_terms":[],"command":{"binary":"rpm","argv":["-Va"]}}]}]},{"id":"docker","name":"Docker operations pack","version":"0.2.21","description":"Operator pack for Docker hosts: read-only inventory and per-container introspection, plus narrow mutators (restart, stop, kill, prune). Includes docker-compose support. The runner uid must be in the docker group; this pack does NOT escalate.","vendor":"emisar","homepage":"https://emisar.dev/packs/docker","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/docker","content_hash":"sha256:c0ee96f35ff6e7a24c0af22c2c62bee708b382c73ab640b5ea30b3133c53cd73","tarball_url":"https://registry.emisar.dev/v1/packs/docker/0.2.21/c0ee96f35ff6e7a24c0af22c2c62bee708b382c73ab640b5ea30b3133c53cd73/pack.tar.gz","requires":{"os":["linux"],"binaries":["docker","bash"]},"detect":{"binaries":[],"processes":["dockerd"],"ports":[]},"setup":{"summary":"Talks to the local Docker daemon on the runner host via its Unix socket — no credentials needed.","notes":["Membership in the docker group is effectively root-equivalent on the host, since a container can mount and write the host filesystem.","Compose actions also need ordinary read access to their selected project files. docker.compose_config needs only that file access, so no universal host-access recipe can name it."],"host_access":[{"actions":["docker.ps","docker.info","docker.version","docker.events_tail","docker.container_top","docker.stats","docker.images","docker.image_inspect","docker.image_history","docker.pull_image","docker.inspect","docker.logs","docker.volume_ls","docker.volume_inspect","docker.volume_prune","docker.network_ls","docker.network_inspect","docker.compose_ps","docker.compose_logs","docker.compose_restart","docker.compose_ls","docker.compose_images","docker.system_df","docker.system_prune","docker.restart","docker.stop","docker.kill"],"requirement":"Connect to the Docker daemon socket.","recipes":[{"name":"Add the Emisar service user to the docker group","commands":["sudo usermod -aG docker emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx docker","sudo -u emisar docker info >/dev/null"],"impact":"Every process running as emisar can control Docker. Docker socket access is effectively root-equivalent because containers can mount and write the host."}]}],"verify":"docker.ps"},"actions":[{"id":"docker.compose_config","title":"Summarize a Docker Compose configuration","summary":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","description":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Does not query or modify containers."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Secret-safe stack summary","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"file":{"maxLength":257,"type":"string"},"images":{"items":{"maxLength":96,"type":"string"},"maxItems":12,"type":"array"},"networks":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"},"profiles":{"items":{"maxLength":32,"type":"string"},"maxItems":6,"type":"array"},"services":{"items":{"maxLength":48,"type":"string"},"maxItems":24,"type":"array"},"truncated":{"additionalProperties":false,"properties":{"images":{"minimum":0,"type":"integer"},"networks":{"minimum":0,"type":"integer"},"profiles":{"minimum":0,"type":"integer"},"services":{"minimum":0,"type":"integer"},"volumes":{"minimum":0,"type":"integer"}},"required":["services","images","networks","volumes","profiles"],"type":"object"},"valid":{"const":true},"volumes":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"}},"required":["valid","file","services","images","networks","volumes","profiles","truncated"],"type":"object"}},{"id":"docker.compose_images","title":"docker compose images","summary":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","description":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Performs one read-only Docker daemon query."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Images used by a project","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[]},{"id":"docker.compose_logs","title":"docker compose logs (last N lines)","summary":"Return the last N lines of logs for one service in a compose project. Read-only.","description":"Return the last N lines of logs for one service in a compose project. Read-only.","kind":"exec","risk":"medium","side_effects":["One docker compose logs invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name from the compose file.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 lines of \"api\" logs","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["service crashed"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","logs","--tail","{{ args.lines }}","{{ args.service }}"]}},{"id":"docker.compose_ls","title":"docker compose ls --all","summary":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","description":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","kind":"exec","risk":"low","side_effects":["One read-only Docker daemon query.","Includes stopped Compose projects."],"args":[],"examples":[{"title":"Discover active and orphaned projects","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["compose","ls","--all","--format","json"]}},{"id":"docker.compose_ps","title":"docker compose ps -a","summary":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","description":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose ps invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Status of services in the prod stack","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":["services down","compose stack"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","ps","-a"]}},{"id":"docker.compose_restart","title":"docker compose restart (one service)","summary":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","description":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) the service's containers.","Containers restart and re-run their entrypoint."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart the \"api\" service","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["bounce service","service hung"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","restart","{{ args.service }}"]}},{"id":"docker.container_top","title":"docker top (processes inside a container)","summary":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","description":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","kind":"exec","risk":"low","side_effects":["One docker top invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Processes inside \"api\"","args":{"container":"api"}}],"search_terms":["runaway process"],"command":{"binary":"docker","argv":["top","{{ args.container }}"]}},{"id":"docker.events_tail","title":"docker events — lifecycle + failures (bounded window)","summary":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","description":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","kind":"script","risk":"low","side_effects":["One docker events query bounded to the requested window.","Read-only."],"args":[{"name":"minutes","type":"integer","required":false,"default":5,"description":"How many minutes of events to replay.","validation":{"min":1,"max":1440}},{"name":"include_exec","type":"boolean","required":false,"default":false,"description":"When true, also show the routine exec_create/exec_start/exec_die events (health-check chatter). Default false."}],"examples":[{"title":"Recent restarts / OOM / health changes (last 5 minutes)","args":{}},{"title":"Last 30 minutes including exec/health-check events","args":{"include_exec":true,"minutes":30}}],"search_terms":["restart loop","crash loop","oom killed"]},{"id":"docker.image_history","title":"docker history","summary":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One docker history invocation.","Read-only, but exposes full layer commands (may include baked-in secrets)."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Layers of nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["image bloat"],"command":{"binary":"docker","argv":["history","--no-trunc","{{ args.image }}"]}},{"id":"docker.image_inspect","title":"docker image inspect","summary":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","description":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","kind":"exec","risk":"high","side_effects":["One docker image inspect invocation.","Read-only."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag or sha256:...).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Inspect nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":[],"command":{"binary":"docker","argv":["image","inspect","{{ args.image }}"]}},{"id":"docker.images","title":"docker images","summary":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","description":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","kind":"exec","risk":"low","side_effects":["One docker images invocation.","Read-only."],"args":[],"examples":[{"title":"List image cache","args":{}}],"search_terms":["old images","image missing"],"command":{"binary":"docker","argv":["images"]}},{"id":"docker.info","title":"docker info","summary":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","description":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","kind":"exec","risk":"low","side_effects":["One docker info invocation.","Read-only."],"args":[],"examples":[{"title":"Daemon summary","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["info"]}},{"id":"docker.inspect","title":"docker inspect (one container)","summary":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","description":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","kind":"exec","risk":"high","side_effects":["One docker inspect invocation.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the \"api\" container","args":{"container":"api"}}],"search_terms":["environment variables","exit reason"],"command":{"binary":"docker","argv":["inspect","{{ args.container }}"]}},{"id":"docker.kill","title":"docker kill (signal)","summary":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","description":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","kind":"exec","risk":"high","side_effects":["Sends the chosen signal directly to the container's PID 1.","SIGKILL: instant termination; in-flight requests dropped."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"KILL","description":"Signal name (KILL, TERM, HUP, USR1, USR2, INT, QUIT).","validation":{"enum":["KILL","TERM","HUP","USR1","USR2","INT","QUIT"]}}],"examples":[{"title":"SIGKILL \"api\" immediately","args":{"container":"api"}},{"title":"SIGHUP \"nginx\" to reload config","args":{"container":"nginx","signal":"HUP"}}],"search_terms":["force stop","stuck container"],"command":{"binary":"docker","argv":["kill","--signal","{{ args.signal }}","{{ args.container }}"]}},{"id":"docker.logs","title":"docker logs (last N lines)","summary":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","description":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","kind":"exec","risk":"medium","side_effects":["One docker logs invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines from \"api\"","args":{"container":"api"}}],"search_terms":["container crashed","crash output","app errors"],"command":{"binary":"docker","argv":["logs","--tail","{{ args.lines }}","{{ args.container }}"]}},{"id":"docker.network_inspect","title":"docker network inspect","summary":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","description":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Network name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the default bridge","args":{"name":"bridge"}}],"search_terms":[],"command":{"binary":"docker","argv":["network","inspect","{{ args.name }}"]}},{"id":"docker.network_ls","title":"docker network ls","summary":"List all docker networks with driver + scope. Read-only.","description":"List all docker networks with driver + scope. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network ls invocation.","Read-only."],"args":[],"examples":[{"title":"All networks","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["network","ls"]}},{"id":"docker.ps","title":"docker ps -a","summary":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","description":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","kind":"exec","risk":"low","side_effects":["One docker ps invocation.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":["container down","container crashed","exited containers"],"command":{"binary":"docker","argv":["ps","-a"]}},{"id":"docker.pull_image","title":"docker pull","summary":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","description":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","kind":"exec","risk":"medium","side_effects":["Outbound HTTPS to the registry.","Writes layers to /var/lib/docker."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Pull nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["download image","update image"],"command":{"binary":"docker","argv":["pull","{{ args.image }}"]}},{"id":"docker.restart","title":"docker restart (one container)","summary":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","description":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) is sent to the container.","In-flight requests on that container are dropped.","Container restarts and re-runs its entrypoint."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"Seconds to wait between SIGTERM and SIGKILL.","validation":{"min":1,"max":600}}],"examples":[{"title":"Restart \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["container down","hung container","unresponsive container","bounce container"],"command":{"binary":"docker","argv":["restart","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.stats","title":"docker stats (one shot)","summary":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","description":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","kind":"exec","risk":"low","side_effects":["One docker stats invocation.","Read-only."],"args":[],"examples":[{"title":"One stats snapshot","args":{}}],"search_terms":["high cpu","cpu spike","memory hog"],"command":{"binary":"docker","argv":["stats","--no-stream"]}},{"id":"docker.stop","title":"docker stop (one container)","summary":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","description":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","kind":"exec","risk":"high","side_effects":["SIGTERM the container; SIGKILL on timeout.","In-flight requests dropped unless the app handles graceful drain."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"SIGTERM → SIGKILL grace seconds.","validation":{"min":1,"max":600}}],"examples":[{"title":"Stop \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["graceful shutdown"],"command":{"binary":"docker","argv":["stop","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.system_df","title":"docker system df","summary":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","description":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","kind":"exec","risk":"low","side_effects":["One docker system df invocation.","Read-only."],"args":[],"examples":[{"title":"Detailed docker disk usage","args":{}}],"search_terms":["disk full","out of disk"],"command":{"binary":"docker","argv":["system","df","-v"]}},{"id":"docker.system_prune","title":"docker system prune","summary":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","description":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","kind":"exec","risk":"high","side_effects":["Deletes stopped containers.","Deletes images not referenced by any container.","Deletes networks not used by any container.","Frees disk; cannot be undone."],"args":[],"examples":[{"title":"Prune stopped containers + dangling images","args":{}}],"search_terms":["free disk space","reclaim space","disk full"],"command":{"binary":"docker","argv":["system","prune","-f"]}},{"id":"docker.version","title":"docker version","summary":"Return client + server version, API version, build info. Read-only.","description":"Return client + server version, API version, build info. Read-only.","kind":"exec","risk":"low","side_effects":["One docker version invocation.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["version"]}},{"id":"docker.volume_inspect","title":"docker volume inspect","summary":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","description":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","kind":"script","risk":"low","side_effects":["One docker volume inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Volume name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect \"pgdata\"","args":{"name":"pgdata"}}],"search_terms":[]},{"id":"docker.volume_ls","title":"docker volume ls","summary":"List all named docker volumes. Read-only.","description":"List all named docker volumes. Read-only.","kind":"exec","risk":"low","side_effects":["One docker volume ls invocation.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["volume","ls"]}},{"id":"docker.volume_prune","title":"docker volume prune (DESTRUCTIVE)","summary":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","description":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","kind":"exec","risk":"critical","side_effects":["Deletes every unattached volume.","Irreversible — there is no recycle bin for docker volumes."],"args":[],"examples":[{"title":"Drop every detached volume","args":{}}],"search_terms":["orphaned volumes"],"command":{"binary":"docker","argv":["volume","prune","-f","--filter","all=true"]}}],"previous_versions":[{"version":"0.2.19","content_hash":"sha256:13dc4f3fbbd23a4b848f2a368a8ed43ce536b0d8c631a6dcbfd7825fb856eb05","tarball_url":"https://registry.emisar.dev/v1/packs/docker/0.2.19/13dc4f3fbbd23a4b848f2a368a8ed43ce536b0d8c631a6dcbfd7825fb856eb05/pack.tar.gz","actions":[{"id":"docker.compose_config","title":"Summarize a Docker Compose configuration","summary":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","description":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Does not query or modify containers."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Secret-safe stack summary","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"file":{"maxLength":257,"type":"string"},"images":{"items":{"maxLength":96,"type":"string"},"maxItems":12,"type":"array"},"networks":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"},"profiles":{"items":{"maxLength":32,"type":"string"},"maxItems":6,"type":"array"},"services":{"items":{"maxLength":48,"type":"string"},"maxItems":24,"type":"array"},"truncated":{"additionalProperties":false,"properties":{"images":{"minimum":0,"type":"integer"},"networks":{"minimum":0,"type":"integer"},"profiles":{"minimum":0,"type":"integer"},"services":{"minimum":0,"type":"integer"},"volumes":{"minimum":0,"type":"integer"}},"required":["services","images","networks","volumes","profiles"],"type":"object"},"valid":{"const":true},"volumes":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"}},"required":["valid","file","services","images","networks","volumes","profiles","truncated"],"type":"object"}},{"id":"docker.compose_images","title":"docker compose images","summary":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","description":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Performs one read-only Docker daemon query."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Images used by a project","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[]},{"id":"docker.compose_logs","title":"docker compose logs (last N lines)","summary":"Return the last N lines of logs for one service in a compose project. Read-only.","description":"Return the last N lines of logs for one service in a compose project. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose logs invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name from the compose file.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 lines of \"api\" logs","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["service crashed"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","logs","--tail","{{ args.lines }}","{{ args.service }}"]}},{"id":"docker.compose_ls","title":"docker compose ls --all","summary":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","description":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","kind":"exec","risk":"low","side_effects":["One read-only Docker daemon query.","Includes stopped Compose projects."],"args":[],"examples":[{"title":"Discover active and orphaned projects","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["compose","ls","--all","--format","json"]}},{"id":"docker.compose_ps","title":"docker compose ps -a","summary":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","description":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose ps invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Status of services in the prod stack","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":["services down","compose stack"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","ps","-a"]}},{"id":"docker.compose_restart","title":"docker compose restart (one service)","summary":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","description":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) the service's containers.","Containers restart and re-run their entrypoint."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart the \"api\" service","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["bounce service","service hung"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","restart","{{ args.service }}"]}},{"id":"docker.container_top","title":"docker top (processes inside a container)","summary":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","description":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","kind":"exec","risk":"low","side_effects":["One docker top invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Processes inside \"api\"","args":{"container":"api"}}],"search_terms":["runaway process"],"command":{"binary":"docker","argv":["top","{{ args.container }}"]}},{"id":"docker.events_tail","title":"docker events — lifecycle + failures (bounded window)","summary":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","description":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","kind":"script","risk":"low","side_effects":["One docker events query bounded to the requested window.","Read-only."],"args":[{"name":"minutes","type":"integer","required":false,"default":5,"description":"How many minutes of events to replay.","validation":{"min":1,"max":1440}},{"name":"include_exec","type":"boolean","required":false,"default":false,"description":"When true, also show the routine exec_create/exec_start/exec_die events (health-check chatter). Default false."}],"examples":[{"title":"Recent restarts / OOM / health changes (last 5 minutes)","args":{}},{"title":"Last 30 minutes including exec/health-check events","args":{"include_exec":true,"minutes":30}}],"search_terms":["restart loop","crash loop","oom killed"]},{"id":"docker.image_history","title":"docker history","summary":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One docker history invocation.","Read-only, but exposes full layer commands (may include baked-in secrets)."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Layers of nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["image bloat"],"command":{"binary":"docker","argv":["history","--no-trunc","{{ args.image }}"]}},{"id":"docker.image_inspect","title":"docker image inspect","summary":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","description":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","kind":"exec","risk":"high","side_effects":["One docker image inspect invocation.","Read-only."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag or sha256:...).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Inspect nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":[],"command":{"binary":"docker","argv":["image","inspect","{{ args.image }}"]}},{"id":"docker.images","title":"docker images","summary":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","description":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","kind":"exec","risk":"low","side_effects":["One docker images invocation.","Read-only."],"args":[],"examples":[{"title":"List image cache","args":{}}],"search_terms":["old images","image missing"],"command":{"binary":"docker","argv":["images"]}},{"id":"docker.info","title":"docker info","summary":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","description":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","kind":"exec","risk":"low","side_effects":["One docker info invocation.","Read-only."],"args":[],"examples":[{"title":"Daemon summary","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["info"]}},{"id":"docker.inspect","title":"docker inspect (one container)","summary":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","description":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","kind":"exec","risk":"high","side_effects":["One docker inspect invocation.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the \"api\" container","args":{"container":"api"}}],"search_terms":["environment variables","exit reason"],"command":{"binary":"docker","argv":["inspect","{{ args.container }}"]}},{"id":"docker.kill","title":"docker kill (signal)","summary":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","description":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","kind":"exec","risk":"high","side_effects":["Sends the chosen signal directly to the container's PID 1.","SIGKILL: instant termination; in-flight requests dropped."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"KILL","description":"Signal name (KILL, TERM, HUP, USR1, USR2, INT, QUIT).","validation":{"enum":["KILL","TERM","HUP","USR1","USR2","INT","QUIT"]}}],"examples":[{"title":"SIGKILL \"api\" immediately","args":{"container":"api"}},{"title":"SIGHUP \"nginx\" to reload config","args":{"container":"nginx","signal":"HUP"}}],"search_terms":["force stop","stuck container"],"command":{"binary":"docker","argv":["kill","--signal","{{ args.signal }}","{{ args.container }}"]}},{"id":"docker.logs","title":"docker logs (last N lines)","summary":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","description":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","kind":"exec","risk":"low","side_effects":["One docker logs invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines from \"api\"","args":{"container":"api"}}],"search_terms":["container crashed","crash output","app errors"],"command":{"binary":"docker","argv":["logs","--tail","{{ args.lines }}","{{ args.container }}"]}},{"id":"docker.network_inspect","title":"docker network inspect","summary":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","description":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Network name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the default bridge","args":{"name":"bridge"}}],"search_terms":[],"command":{"binary":"docker","argv":["network","inspect","{{ args.name }}"]}},{"id":"docker.network_ls","title":"docker network ls","summary":"List all docker networks with driver + scope. Read-only.","description":"List all docker networks with driver + scope. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network ls invocation.","Read-only."],"args":[],"examples":[{"title":"All networks","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["network","ls"]}},{"id":"docker.ps","title":"docker ps -a","summary":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","description":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","kind":"exec","risk":"low","side_effects":["One docker ps invocation.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":["container down","container crashed","exited containers"],"command":{"binary":"docker","argv":["ps","-a"]}},{"id":"docker.pull_image","title":"docker pull","summary":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","description":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","kind":"exec","risk":"medium","side_effects":["Outbound HTTPS to the registry.","Writes layers to /var/lib/docker."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Pull nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["download image","update image"],"command":{"binary":"docker","argv":["pull","{{ args.image }}"]}},{"id":"docker.restart","title":"docker restart (one container)","summary":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","description":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) is sent to the container.","In-flight requests on that container are dropped.","Container restarts and re-runs its entrypoint."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"Seconds to wait between SIGTERM and SIGKILL.","validation":{"min":1,"max":600}}],"examples":[{"title":"Restart \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["container down","hung container","unresponsive container","bounce container"],"command":{"binary":"docker","argv":["restart","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.stats","title":"docker stats (one shot)","summary":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","description":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","kind":"exec","risk":"low","side_effects":["One docker stats invocation.","Read-only."],"args":[],"examples":[{"title":"One stats snapshot","args":{}}],"search_terms":["high cpu","cpu spike","memory hog"],"command":{"binary":"docker","argv":["stats","--no-stream"]}},{"id":"docker.stop","title":"docker stop (one container)","summary":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","description":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","kind":"exec","risk":"high","side_effects":["SIGTERM the container; SIGKILL on timeout.","In-flight requests dropped unless the app handles graceful drain."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"SIGTERM → SIGKILL grace seconds.","validation":{"min":1,"max":600}}],"examples":[{"title":"Stop \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["graceful shutdown"],"command":{"binary":"docker","argv":["stop","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.system_df","title":"docker system df","summary":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","description":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","kind":"exec","risk":"low","side_effects":["One docker system df invocation.","Read-only."],"args":[],"examples":[{"title":"Detailed docker disk usage","args":{}}],"search_terms":["disk full","out of disk"],"command":{"binary":"docker","argv":["system","df","-v"]}},{"id":"docker.system_prune","title":"docker system prune","summary":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","description":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","kind":"exec","risk":"high","side_effects":["Deletes stopped containers.","Deletes images not referenced by any container.","Deletes networks not used by any container.","Frees disk; cannot be undone."],"args":[],"examples":[{"title":"Prune stopped containers + dangling images","args":{}}],"search_terms":["free disk space","reclaim space","disk full"],"command":{"binary":"docker","argv":["system","prune","-f"]}},{"id":"docker.version","title":"docker version","summary":"Return client + server version, API version, build info. Read-only.","description":"Return client + server version, API version, build info. Read-only.","kind":"exec","risk":"low","side_effects":["One docker version invocation.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["version"]}},{"id":"docker.volume_inspect","title":"docker volume inspect","summary":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","description":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","kind":"script","risk":"low","side_effects":["One docker volume inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Volume name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect \"pgdata\"","args":{"name":"pgdata"}}],"search_terms":[]},{"id":"docker.volume_ls","title":"docker volume ls","summary":"List all named docker volumes. Read-only.","description":"List all named docker volumes. Read-only.","kind":"exec","risk":"low","side_effects":["One docker volume ls invocation.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["volume","ls"]}},{"id":"docker.volume_prune","title":"docker volume prune (DESTRUCTIVE)","summary":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","description":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","kind":"exec","risk":"critical","side_effects":["Deletes every unattached volume.","Irreversible — there is no recycle bin for docker volumes."],"args":[],"examples":[{"title":"Drop every detached volume","args":{}}],"search_terms":["orphaned volumes"],"command":{"binary":"docker","argv":["volume","prune","-f","--filter","all=true"]}}]},{"version":"0.2.17","content_hash":"sha256:f09ebfe9b5da673ecbfadd4d2d8a77b1ad2ec9af951c8c58ebeaaca21bdc0852","tarball_url":"https://registry.emisar.dev/v1/packs/docker/0.2.17/f09ebfe9b5da673ecbfadd4d2d8a77b1ad2ec9af951c8c58ebeaaca21bdc0852/pack.tar.gz","actions":[{"id":"docker.compose_config","title":"Summarize a Docker Compose configuration","summary":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","description":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Does not query or modify containers."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Secret-safe stack summary","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"file":{"maxLength":257,"type":"string"},"images":{"items":{"maxLength":96,"type":"string"},"maxItems":12,"type":"array"},"networks":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"},"profiles":{"items":{"maxLength":32,"type":"string"},"maxItems":6,"type":"array"},"services":{"items":{"maxLength":48,"type":"string"},"maxItems":24,"type":"array"},"truncated":{"additionalProperties":false,"properties":{"images":{"minimum":0,"type":"integer"},"networks":{"minimum":0,"type":"integer"},"profiles":{"minimum":0,"type":"integer"},"services":{"minimum":0,"type":"integer"},"volumes":{"minimum":0,"type":"integer"}},"required":["services","images","networks","volumes","profiles"],"type":"object"},"valid":{"const":true},"volumes":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"}},"required":["valid","file","services","images","networks","volumes","profiles","truncated"],"type":"object"}},{"id":"docker.compose_images","title":"docker compose images","summary":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","description":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Performs one read-only Docker daemon query."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Images used by a project","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[]},{"id":"docker.compose_logs","title":"docker compose logs (last N lines)","summary":"Return the last N lines of logs for one service in a compose project. Read-only.","description":"Return the last N lines of logs for one service in a compose project. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose logs invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name from the compose file.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 lines of \"api\" logs","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["service crashed"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","logs","--tail","{{ args.lines }}","{{ args.service }}"]}},{"id":"docker.compose_ls","title":"docker compose ls --all","summary":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","description":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","kind":"exec","risk":"low","side_effects":["One read-only Docker daemon query.","Includes stopped Compose projects."],"args":[],"examples":[{"title":"Discover active and orphaned projects","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["compose","ls","--all","--format","json"]}},{"id":"docker.compose_ps","title":"docker compose ps -a","summary":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","description":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose ps invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Status of services in the prod stack","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":["services down","compose stack"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","ps","-a"]}},{"id":"docker.compose_restart","title":"docker compose restart (one service)","summary":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","description":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) the service's containers.","Containers restart and re-run their entrypoint."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart the \"api\" service","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["bounce service","service hung"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","restart","{{ args.service }}"]}},{"id":"docker.container_top","title":"docker top (processes inside a container)","summary":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","description":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","kind":"exec","risk":"low","side_effects":["One docker top invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Processes inside \"api\"","args":{"container":"api"}}],"search_terms":["runaway process"],"command":{"binary":"docker","argv":["top","{{ args.container }}"]}},{"id":"docker.events_tail","title":"docker events — lifecycle + failures (bounded window)","summary":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","description":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","kind":"script","risk":"low","side_effects":["One docker events query bounded to the requested window.","Read-only."],"args":[{"name":"minutes","type":"integer","required":false,"default":5,"description":"How many minutes of events to replay.","validation":{"min":1,"max":1440}},{"name":"include_exec","type":"boolean","required":false,"default":false,"description":"When true, also show the routine exec_create/exec_start/exec_die events (health-check chatter). Default false."}],"examples":[{"title":"Recent restarts / OOM / health changes (last 5 minutes)","args":{}},{"title":"Last 30 minutes including exec/health-check events","args":{"include_exec":true,"minutes":30}}],"search_terms":["restart loop","crash loop","oom killed"]},{"id":"docker.image_history","title":"docker history","summary":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One docker history invocation.","Read-only, but exposes full layer commands (may include baked-in secrets)."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Layers of nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["image bloat"],"command":{"binary":"docker","argv":["history","--no-trunc","{{ args.image }}"]}},{"id":"docker.image_inspect","title":"docker image inspect","summary":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","description":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","kind":"exec","risk":"high","side_effects":["One docker image inspect invocation.","Read-only."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag or sha256:...).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Inspect nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":[],"command":{"binary":"docker","argv":["image","inspect","{{ args.image }}"]}},{"id":"docker.images","title":"docker images","summary":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","description":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","kind":"exec","risk":"low","side_effects":["One docker images invocation.","Read-only."],"args":[],"examples":[{"title":"List image cache","args":{}}],"search_terms":["old images","image missing"],"command":{"binary":"docker","argv":["images"]}},{"id":"docker.info","title":"docker info","summary":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","description":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","kind":"exec","risk":"low","side_effects":["One docker info invocation.","Read-only."],"args":[],"examples":[{"title":"Daemon summary","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["info"]}},{"id":"docker.inspect","title":"docker inspect (one container)","summary":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","description":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","kind":"exec","risk":"high","side_effects":["One docker inspect invocation.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the \"api\" container","args":{"container":"api"}}],"search_terms":["environment variables","exit reason"],"command":{"binary":"docker","argv":["inspect","{{ args.container }}"]}},{"id":"docker.kill","title":"docker kill (signal)","summary":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","description":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","kind":"exec","risk":"high","side_effects":["Sends the chosen signal directly to the container's PID 1.","SIGKILL: instant termination; in-flight requests dropped."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"KILL","description":"Signal name (KILL, TERM, HUP, USR1, USR2, INT, QUIT).","validation":{"enum":["KILL","TERM","HUP","USR1","USR2","INT","QUIT"]}}],"examples":[{"title":"SIGKILL \"api\" immediately","args":{"container":"api"}},{"title":"SIGHUP \"nginx\" to reload config","args":{"container":"nginx","signal":"HUP"}}],"search_terms":["force stop","stuck container"],"command":{"binary":"docker","argv":["kill","--signal","{{ args.signal }}","{{ args.container }}"]}},{"id":"docker.logs","title":"docker logs (last N lines)","summary":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","description":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","kind":"exec","risk":"low","side_effects":["One docker logs invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines from \"api\"","args":{"container":"api"}}],"search_terms":["container crashed","crash output","app errors"],"command":{"binary":"docker","argv":["logs","--tail","{{ args.lines }}","{{ args.container }}"]}},{"id":"docker.network_inspect","title":"docker network inspect","summary":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","description":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Network name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the default bridge","args":{"name":"bridge"}}],"search_terms":[],"command":{"binary":"docker","argv":["network","inspect","{{ args.name }}"]}},{"id":"docker.network_ls","title":"docker network ls","summary":"List all docker networks with driver + scope. Read-only.","description":"List all docker networks with driver + scope. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network ls invocation.","Read-only."],"args":[],"examples":[{"title":"All networks","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["network","ls"]}},{"id":"docker.ps","title":"docker ps -a","summary":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","description":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","kind":"exec","risk":"low","side_effects":["One docker ps invocation.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":["container down","container crashed","exited containers"],"command":{"binary":"docker","argv":["ps","-a"]}},{"id":"docker.pull_image","title":"docker pull","summary":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","description":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","kind":"exec","risk":"medium","side_effects":["Outbound HTTPS to the registry.","Writes layers to /var/lib/docker."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Pull nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["download image","update image"],"command":{"binary":"docker","argv":["pull","{{ args.image }}"]}},{"id":"docker.restart","title":"docker restart (one container)","summary":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","description":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) is sent to the container.","In-flight requests on that container are dropped.","Container restarts and re-runs its entrypoint."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"Seconds to wait between SIGTERM and SIGKILL.","validation":{"min":1,"max":600}}],"examples":[{"title":"Restart \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["container down","hung container","unresponsive container","bounce container"],"command":{"binary":"docker","argv":["restart","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.stats","title":"docker stats (one shot)","summary":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","description":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","kind":"exec","risk":"low","side_effects":["One docker stats invocation.","Read-only."],"args":[],"examples":[{"title":"One stats snapshot","args":{}}],"search_terms":["high cpu","cpu spike","memory hog"],"command":{"binary":"docker","argv":["stats","--no-stream"]}},{"id":"docker.stop","title":"docker stop (one container)","summary":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","description":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","kind":"exec","risk":"high","side_effects":["SIGTERM the container; SIGKILL on timeout.","In-flight requests dropped unless the app handles graceful drain."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"SIGTERM → SIGKILL grace seconds.","validation":{"min":1,"max":600}}],"examples":[{"title":"Stop \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["graceful shutdown"],"command":{"binary":"docker","argv":["stop","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.system_df","title":"docker system df","summary":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","description":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","kind":"exec","risk":"low","side_effects":["One docker system df invocation.","Read-only."],"args":[],"examples":[{"title":"Detailed docker disk usage","args":{}}],"search_terms":["disk full","out of disk"],"command":{"binary":"docker","argv":["system","df","-v"]}},{"id":"docker.system_prune","title":"docker system prune","summary":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","description":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","kind":"exec","risk":"high","side_effects":["Deletes stopped containers.","Deletes images not referenced by any container.","Deletes networks not used by any container.","Frees disk; cannot be undone."],"args":[],"examples":[{"title":"Prune stopped containers + dangling images","args":{}}],"search_terms":["free disk space","reclaim space","disk full"],"command":{"binary":"docker","argv":["system","prune","-f"]}},{"id":"docker.version","title":"docker version","summary":"Return client + server version, API version, build info. Read-only.","description":"Return client + server version, API version, build info. Read-only.","kind":"exec","risk":"low","side_effects":["One docker version invocation.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["version"]}},{"id":"docker.volume_inspect","title":"docker volume inspect","summary":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","description":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","kind":"script","risk":"low","side_effects":["One docker volume inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Volume name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect \"pgdata\"","args":{"name":"pgdata"}}],"search_terms":[]},{"id":"docker.volume_ls","title":"docker volume ls","summary":"List all named docker volumes. Read-only.","description":"List all named docker volumes. Read-only.","kind":"exec","risk":"low","side_effects":["One docker volume ls invocation.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["volume","ls"]}},{"id":"docker.volume_prune","title":"docker volume prune (DESTRUCTIVE)","summary":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","description":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","kind":"exec","risk":"critical","side_effects":["Deletes every unattached volume.","Irreversible — there is no recycle bin for docker volumes."],"args":[],"examples":[{"title":"Drop every detached volume","args":{}}],"search_terms":["orphaned volumes"],"command":{"binary":"docker","argv":["volume","prune","-f","--filter","all=true"]}}]},{"version":"0.2.16","content_hash":"sha256:dfce79827cdae16289c7b8a0c335357b688661c15008835d7c6d768925885f9c","tarball_url":"https://registry.emisar.dev/v1/packs/docker/0.2.16/dfce79827cdae16289c7b8a0c335357b688661c15008835d7c6d768925885f9c/pack.tar.gz","actions":[{"id":"docker.compose_config","title":"Summarize a Docker Compose configuration","summary":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","description":"Parse one contained Compose file without interpolation or environment resolution, then return only service, image, network, volume, and profile names as sorted, capped samples with per-list truncation counts. Raw YAML, environment values, secrets, labels, and build arguments are never returned.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Does not query or modify containers."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Secret-safe stack summary","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"file":{"maxLength":257,"type":"string"},"images":{"items":{"maxLength":96,"type":"string"},"maxItems":12,"type":"array"},"networks":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"},"profiles":{"items":{"maxLength":32,"type":"string"},"maxItems":6,"type":"array"},"services":{"items":{"maxLength":48,"type":"string"},"maxItems":24,"type":"array"},"truncated":{"additionalProperties":false,"properties":{"images":{"minimum":0,"type":"integer"},"networks":{"minimum":0,"type":"integer"},"profiles":{"minimum":0,"type":"integer"},"services":{"minimum":0,"type":"integer"},"volumes":{"minimum":0,"type":"integer"}},"required":["services","images","networks","volumes","profiles"],"type":"object"},"valid":{"const":true},"volumes":{"items":{"maxLength":48,"type":"string"},"maxItems":8,"type":"array"}},"required":["valid","file","services","images","networks","volumes","profiles","truncated"],"type":"object"}},{"id":"docker.compose_images","title":"docker compose images","summary":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","description":"List images used by containers already created for one contained Compose project. This reports container image IDs and tags, not configured image references for services that have never been created.","kind":"script","risk":"low","side_effects":["Parses one Compose file beneath an approved deployment root.","Performs one read-only Docker daemon query."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Images used by a project","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":[]},{"id":"docker.compose_logs","title":"docker compose logs (last N lines)","summary":"Return the last N lines of logs for one service in a compose project. Read-only.","description":"Return the last N lines of logs for one service in a compose project. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose logs invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name from the compose file.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 lines of \"api\" logs","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["service crashed"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","logs","--tail","{{ args.lines }}","{{ args.service }}"]}},{"id":"docker.compose_ls","title":"docker compose ls --all","summary":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","description":"List all known Compose projects, including projects with stopped containers, with their status and resolved configuration-file paths.","kind":"exec","risk":"low","side_effects":["One read-only Docker daemon query.","Includes stopped Compose projects."],"args":[],"examples":[{"title":"Discover active and orphaned projects","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["compose","ls","--all","--format","json"]}},{"id":"docker.compose_ps","title":"docker compose ps -a","summary":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","description":"List services in a compose project (running + stopped). The compose-file path is required and pattern-restricted. Read-only.","kind":"exec","risk":"low","side_effects":["One docker compose ps invocation.","Read-only."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}}],"examples":[{"title":"Status of services in the prod stack","args":{"file":"/opt/stack/docker-compose.yml"}}],"search_terms":["services down","compose stack"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","ps","-a"]}},{"id":"docker.compose_restart","title":"docker compose restart (one service)","summary":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","description":"Restart ONE service in a compose project. SIGTERM with the configured stop_grace_period, then SIGKILL, then start. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) the service's containers.","Containers restart and re-run their entrypoint."],"args":[{"name":"file","type":"string","required":true,"description":"Path to docker-compose.yml.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/opt","/srv","/var/www","/data","/usr/local"]}},{"name":"service","type":"string","required":true,"description":"Service name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart the \"api\" service","args":{"file":"/opt/stack/docker-compose.yml","service":"api"}}],"search_terms":["bounce service","service hung"],"command":{"binary":"docker","argv":["compose","-f","{{ args.file }}","restart","{{ args.service }}"]}},{"id":"docker.container_top","title":"docker top (processes inside a container)","summary":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","description":"List processes running inside one container (via `docker top`). Use when the container's CPU is hot but you don't know which child process is the offender. Read-only.","kind":"exec","risk":"low","side_effects":["One docker top invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Processes inside \"api\"","args":{"container":"api"}}],"search_terms":["runaway process"],"command":{"binary":"docker","argv":["top","{{ args.container }}"]}},{"id":"docker.events_tail","title":"docker events — lifecycle + failures (bounded window)","summary":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","description":"Replay docker daemon events from the last N minutes, focused on container lifecycle and failures (create, start, restart, stop, die, kill, oom, destroy, health_status) — the \"why did the container restart / OOM / go unhealthy?\" read. Routine health-check exec_* chatter is excluded by default so the real signal is not drowned out; set include_exec=true to add exec_create/exec_start/ exec_die. Read-only.","kind":"script","risk":"low","side_effects":["One docker events query bounded to the requested window.","Read-only."],"args":[{"name":"minutes","type":"integer","required":false,"default":5,"description":"How many minutes of events to replay.","validation":{"min":1,"max":1440}},{"name":"include_exec","type":"boolean","required":false,"default":false,"description":"When true, also show the routine exec_create/exec_start/exec_die events (health-check chatter). Default false."}],"examples":[{"title":"Recent restarts / OOM / health changes (last 5 minutes)","args":{}},{"title":"Last 30 minutes including exec/health-check events","args":{"include_exec":true,"minutes":30}}],"search_terms":["restart loop","crash loop","oom killed"]},{"id":"docker.image_history","title":"docker history","summary":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Return the layer-by-layer build history of one image — useful for tracing \"where did this 2 GB layer come from?\" Read-only. History runs with --no-trunc, so CREATED BY lines carry the complete Dockerfile commands, including any `ENV`/`ARG` secret a badly-built image baked in; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One docker history invocation.","Read-only, but exposes full layer commands (may include baked-in secrets)."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Layers of nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["image bloat"],"command":{"binary":"docker","argv":["history","--no-trunc","{{ args.image }}"]}},{"id":"docker.image_inspect","title":"docker image inspect","summary":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","description":"Return the full JSON inspect document for one image — labels, config, exposed ports, build history root, and the image's baked-in env. Image env is build-time config, but a badly-built image can bake a secret in; the runner's redaction is a pattern-bound backstop. Read-only.","kind":"exec","risk":"high","side_effects":["One docker image inspect invocation.","Read-only."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag or sha256:...).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Inspect nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":[],"command":{"binary":"docker","argv":["image","inspect","{{ args.image }}"]}},{"id":"docker.images","title":"docker images","summary":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","description":"List images on the host. Use to verify expected tags are present before a deploy or to find old images consuming disk. Read-only.","kind":"exec","risk":"low","side_effects":["One docker images invocation.","Read-only."],"args":[],"examples":[{"title":"List image cache","args":{}}],"search_terms":["old images","image missing"],"command":{"binary":"docker","argv":["images"]}},{"id":"docker.info","title":"docker info","summary":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","description":"`docker info` — daemon version, storage driver, total containers/images, host resources. Read-only.","kind":"exec","risk":"low","side_effects":["One docker info invocation.","Read-only."],"args":[],"examples":[{"title":"Daemon summary","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["info"]}},{"id":"docker.inspect","title":"docker inspect (one container)","summary":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","description":"Return the full JSON inspect document for one container — state, exit code, restart count, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (DB URLs, API keys, values passed with -e), so this is approval-gated; the runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret. Container name is pattern-restricted. Read-only.","kind":"exec","risk":"high","side_effects":["One docker inspect invocation.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the \"api\" container","args":{"container":"api"}}],"search_terms":["environment variables","exit reason"],"command":{"binary":"docker","argv":["inspect","{{ args.container }}"]}},{"id":"docker.kill","title":"docker kill (signal)","summary":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","description":"Send a Unix signal to one container's main process. Default is SIGKILL — immediate, no graceful drain. Specify `signal:` for SIGTERM (graceful) or SIGHUP (reload).","kind":"exec","risk":"high","side_effects":["Sends the chosen signal directly to the container's PID 1.","SIGKILL: instant termination; in-flight requests dropped."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"KILL","description":"Signal name (KILL, TERM, HUP, USR1, USR2, INT, QUIT).","validation":{"enum":["KILL","TERM","HUP","USR1","USR2","INT","QUIT"]}}],"examples":[{"title":"SIGKILL \"api\" immediately","args":{"container":"api"}},{"title":"SIGHUP \"nginx\" to reload config","args":{"container":"nginx","signal":"HUP"}}],"search_terms":["force stop","stuck container"],"command":{"binary":"docker","argv":["kill","--signal","{{ args.signal }}","{{ args.container }}"]}},{"id":"docker.logs","title":"docker logs (last N lines)","summary":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","description":"Return the last N log lines for one container. Container name is pattern-restricted to alnum + \"_-.\". Read-only. Output passes through the runner's redaction pipeline.","kind":"exec","risk":"low","side_effects":["One docker logs invocation.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines from \"api\"","args":{"container":"api"}}],"search_terms":["container crashed","crash output","app errors"],"command":{"binary":"docker","argv":["logs","--tail","{{ args.lines }}","{{ args.container }}"]}},{"id":"docker.network_inspect","title":"docker network inspect","summary":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","description":"Return the JSON inspect document for one network — subnet, gateway, containers attached, driver options. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Network name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect the default bridge","args":{"name":"bridge"}}],"search_terms":[],"command":{"binary":"docker","argv":["network","inspect","{{ args.name }}"]}},{"id":"docker.network_ls","title":"docker network ls","summary":"List all docker networks with driver + scope. Read-only.","description":"List all docker networks with driver + scope. Read-only.","kind":"exec","risk":"low","side_effects":["One docker network ls invocation.","Read-only."],"args":[],"examples":[{"title":"All networks","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["network","ls"]}},{"id":"docker.ps","title":"docker ps -a","summary":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","description":"List all containers (running + stopped). Returns id, image, status, ports, names. Always includes stopped containers — for triage you almost always want to see the dead ones too. Read-only.","kind":"exec","risk":"low","side_effects":["One docker ps invocation.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":["container down","container crashed","exited containers"],"command":{"binary":"docker","argv":["ps","-a"]}},{"id":"docker.pull_image","title":"docker pull","summary":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","description":"Pull one image from its configured registry. Network + disk intensive; image-ref restricted to safe characters. Idempotent — re-pulling an existing tag re-checks the digest.","kind":"exec","risk":"medium","side_effects":["Outbound HTTPS to the registry.","Writes layers to /var/lib/docker."],"args":[{"name":"image","type":"string","required":true,"description":"Image ref (name:tag).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_./@:\\-]{0,255}$"}}],"examples":[{"title":"Pull nginx:latest","args":{"image":"nginx:latest"}}],"search_terms":["download image","update image"],"command":{"binary":"docker","argv":["pull","{{ args.image }}"]}},{"id":"docker.restart","title":"docker restart (one container)","summary":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","description":"Restart one container. Sends SIGTERM, waits for the configured stop-timeout, then SIGKILL, then re-starts. In-flight requests are dropped; the container's restart policy still applies after this call. Container name is pattern-restricted.","kind":"exec","risk":"high","side_effects":["SIGTERM (then SIGKILL) is sent to the container.","In-flight requests on that container are dropped.","Container restarts and re-runs its entrypoint."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"Seconds to wait between SIGTERM and SIGKILL.","validation":{"min":1,"max":600}}],"examples":[{"title":"Restart \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["container down","hung container","unresponsive container","bounce container"],"command":{"binary":"docker","argv":["restart","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.stats","title":"docker stats (one shot)","summary":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","description":"Capture one frame of `docker stats` (CPU%, mem usage/limit, net I/O, block I/O, PIDs) for every running container. Read-only.","kind":"exec","risk":"low","side_effects":["One docker stats invocation.","Read-only."],"args":[],"examples":[{"title":"One stats snapshot","args":{}}],"search_terms":["high cpu","cpu spike","memory hog"],"command":{"binary":"docker","argv":["stats","--no-stream"]}},{"id":"docker.stop","title":"docker stop (one container)","summary":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","description":"Stop one container — SIGTERM, then SIGKILL after the configured timeout. Container stays around (for inspection/restart). Use `docker.kill` for immediate SIGKILL.","kind":"exec","risk":"high","side_effects":["SIGTERM the container; SIGKILL on timeout.","In-flight requests dropped unless the app handles graceful drain."],"args":[{"name":"container","type":"string","required":true,"description":"Container name or ID.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}},{"name":"timeout","type":"integer","required":false,"default":10,"description":"SIGTERM → SIGKILL grace seconds.","validation":{"min":1,"max":600}}],"examples":[{"title":"Stop \"api\" with 10s grace","args":{"container":"api"}}],"search_terms":["graceful shutdown"],"command":{"binary":"docker","argv":["stop","-t","{{ args.timeout }}","{{ args.container }}"]}},{"id":"docker.system_df","title":"docker system df","summary":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","description":"Report disk usage by docker (images, containers, volumes, build cache). Use to plan a prune. Read-only.","kind":"exec","risk":"low","side_effects":["One docker system df invocation.","Read-only."],"args":[],"examples":[{"title":"Detailed docker disk usage","args":{}}],"search_terms":["disk full","out of disk"],"command":{"binary":"docker","argv":["system","df","-v"]}},{"id":"docker.system_prune","title":"docker system prune","summary":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","description":"Remove stopped containers, dangling images, and unused networks. Does NOT remove unused volumes (intentional — volume data is the riskiest thing to delete). Run `docker.system_df` first to scope what will be freed. Irreversible.","kind":"exec","risk":"high","side_effects":["Deletes stopped containers.","Deletes images not referenced by any container.","Deletes networks not used by any container.","Frees disk; cannot be undone."],"args":[],"examples":[{"title":"Prune stopped containers + dangling images","args":{}}],"search_terms":["free disk space","reclaim space","disk full"],"command":{"binary":"docker","argv":["system","prune","-f"]}},{"id":"docker.version","title":"docker version","summary":"Return client + server version, API version, build info. Read-only.","description":"Return client + server version, API version, build info. Read-only.","kind":"exec","risk":"low","side_effects":["One docker version invocation.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["version"]}},{"id":"docker.volume_inspect","title":"docker volume inspect","summary":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","description":"Show one volume's driver, scope, mountpoint, creation time, and labels, projected from `docker volume inspect`. Driver options and driver status are never returned — CIFS/NFS and plugin volume options can carry mount credentials. Read-only.","kind":"script","risk":"low","side_effects":["One docker volume inspect invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Volume name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Inspect \"pgdata\"","args":{"name":"pgdata"}}],"search_terms":[]},{"id":"docker.volume_ls","title":"docker volume ls","summary":"List all named docker volumes. Read-only.","description":"List all named docker volumes. Read-only.","kind":"exec","risk":"low","side_effects":["One docker volume ls invocation.","Read-only."],"args":[],"examples":[{"title":"All volumes","args":{}}],"search_terms":[],"command":{"binary":"docker","argv":["volume","ls"]}},{"id":"docker.volume_prune","title":"docker volume prune (DESTRUCTIVE)","summary":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","description":"Remove every volume not attached to a container. **Permanently deletes the data on them.** Use only on caches and dev hosts. Pair with `docker.volume_ls` first to confirm what's loose.","kind":"exec","risk":"critical","side_effects":["Deletes every unattached volume.","Irreversible — there is no recycle bin for docker volumes."],"args":[],"examples":[{"title":"Drop every detached volume","args":{}}],"search_terms":["orphaned volumes"],"command":{"binary":"docker","argv":["volume","prune","-f","--filter","all=true"]}}]}],"retired_below":"0.2.14"},{"id":"elasticsearch","name":"Elasticsearch / OpenSearch ops","version":"0.1.19","description":"Cluster + index introspection plus narrow mutators (cache_clear, force_merge, flush, close_index). Auth via ELASTIC_USER + ELASTIC_PASSWORD env vars on the runner host. Does NOT include delete_index — too easy to misuse.","vendor":"emisar","homepage":"https://emisar.dev/packs/elasticsearch","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/elasticsearch","content_hash":"sha256:8b72e652c97072d3c477ff80e26f0b03f7f50fbd00b88e3abd425617f5486a90","tarball_url":"https://registry.emisar.dev/v1/packs/elasticsearch/0.1.19/8b72e652c97072d3c477ff80e26f0b03f7f50fbd00b88e3abd425617f5486a90/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","bash"]},"detect":{"binaries":["elasticsearch"],"processes":["elasticsearch"],"ports":[9200]},"setup":{"summary":"Each action expands `ELASTIC_URL`, `ELASTIC_USER`, and `ELASTIC_PASSWORD` on the runner host and passes them to curl as the target URL and HTTP basic-auth credentials.","env":[{"name":"ELASTIC_URL","description":"Base URL of the cluster, scheme and port included. Defaults to a local node.","default":"http://127.0.0.1:9200","example":"https://es.internal:9200"},{"name":"ELASTIC_USER","required":true,"description":"Username for HTTP basic auth; needs privileges for the actions you enable.","example":"elastic"},{"name":"ELASTIC_PASSWORD","required":true,"description":"Password for `ELASTIC_USER`."}],"notes":["Create the user in Kibana under Stack Management → Security → Users, or with bin/elasticsearch-users useradd on a self-managed node. The reads need the monitor cluster privilege plus read on the target indices.","curl does not read these on its own; the actions build the -u credential and the URL from them, so all three must be allowlisted in `inherit_env`.","For a cluster without security enabled, point `ELASTIC_URL` at the HTTP endpoint and set `ELASTIC_USER` / `ELASTIC_PASSWORD` to any non-empty placeholder — the basic-auth header is sent unconditionally.","Mutators (cache_clear, force_merge, flush, close_index) need a role with manage privileges on the target indices."],"verify":"es.cluster_health"},"actions":[{"id":"es.cache_clear","title":"POST /<index>/_cache/clear","summary":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","description":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","kind":"script","risk":"high","side_effects":["Drops cached data for the index.","Subsequent queries slow until caches re-warm."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Clear caches for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.cat_aliases","title":"GET /_cat/aliases","summary":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","description":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Aliases","args":{}}],"search_terms":[]},{"id":"es.cat_indices","title":"GET /_cat/indices","summary":"List every index with its primary count, doc count, store size. Sorted by size descending.","description":"List every index with its primary count, doc count, store size. Sorted by size descending.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All indices","args":{}}],"search_terms":[]},{"id":"es.cat_nodes","title":"GET /_cat/nodes","summary":"List nodes with heap, RAM, CPU, load, role. Read-only.","description":"List nodes with heap, RAM, CPU, load, role. Read-only.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[]},{"id":"es.cat_recovery","title":"GET /_cat/recovery","summary":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","description":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Active recoveries","args":{}}],"search_terms":[]},{"id":"es.cat_segments","title":"GET /_cat/segments","summary":"Show per-segment doc + bytes counts. Use to plan a force_merge.","description":"Show per-segment doc + bytes counts. Use to plan a force_merge.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Segments","args":{}}],"search_terms":[]},{"id":"es.cat_shards","title":"GET /_cat/shards","summary":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","description":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All shards","args":{}}],"search_terms":[]},{"id":"es.cat_thread_pool","title":"GET /_cat/thread_pool","summary":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","description":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Thread pools","args":{}}],"search_terms":[]},{"id":"es.close_index","title":"POST /<index>/_close","summary":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","description":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","kind":"script","risk":"critical","side_effects":["Index becomes read-only AND unsearchable.","All in-flight requests against it fail.","Reverse with `_open` (not part of this pack)."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Close one index","args":{"index":"logs-2025-12-31"}}],"search_terms":[]},{"id":"es.cluster_allocation_explain","title":"POST /_cluster/allocation/explain","summary":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","description":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","kind":"script","risk":"low","side_effects":["One POST request.","Read-only."],"args":[],"examples":[{"title":"Why is a shard unassigned?","args":{}}],"search_terms":[]},{"id":"es.cluster_health","title":"GET /_cluster/health","summary":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","description":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster health","args":{}}],"search_terms":[]},{"id":"es.cluster_settings","title":"GET /_cluster/settings","summary":"Return persistent + transient cluster-level settings.","description":"Return persistent + transient cluster-level settings.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster settings","args":{}}],"search_terms":[]},{"id":"es.flush","title":"POST /<index>/_flush (flush index)","summary":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. (Looking for synced flush? That API was removed in ES 8.0; a normal flush gives the same recovery benefit.)","description":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. (Looking for synced flush? That API was removed in ES 8.0; a normal flush gives the same recovery benefit.)","kind":"script","risk":"medium","side_effects":["Brief pause to write segments to disk."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Flush an index","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.force_merge","title":"POST /<index>/_forcemerge","summary":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","description":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","kind":"script","risk":"high","side_effects":["Heavy IO + CPU on each node holding shards.","Disk space may spike before reclaiming."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"max_segments","type":"integer","required":false,"default":1,"description":"Target segment count per shard.","validation":{"min":1,"max":100}}],"examples":[{"title":"Force-merge yesterday's logs","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.index_count","title":"GET /<index>/_count","summary":"Return the document count for one index.","description":"Return the document count for one index.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Doc count","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.index_mapping","title":"GET /<index>/_mapping","summary":"Return the field mappings for one index.","description":"Return the field mappings for one index.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Mapping for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.index_settings","title":"GET /<index>/_settings","summary":"Return one index's settings.","description":"Return one index's settings.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Settings for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.index_stats","title":"GET /<index>/_stats","summary":"Show index-level stats — docs, store, indexing/search rates, fielddata.","description":"Show index-level stats — docs, store, indexing/search rates, fielddata.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Stats for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[]},{"id":"es.pending_tasks","title":"GET /_cluster/pending_tasks","summary":"List pending master tasks. A growing queue here means the master can't keep up.","description":"List pending master tasks. A growing queue here means the master can't keep up.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Pending master tasks","args":{}}],"search_terms":[]},{"id":"es.snapshot_list","title":"GET /_snapshot/<repo>/_all","summary":"List snapshots in one repository.","description":"List snapshots in one repository.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Snapshot repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshots in 's3-backup'","args":{"repository":"s3-backup"}}],"search_terms":[]},{"id":"es.snapshot_status","title":"GET /_snapshot/<repo>/<snap>/_status","summary":"Return the in-progress (or completed) status of one snapshot.","description":"Return the in-progress (or completed) status of one snapshot.","kind":"script","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"snapshot","type":"string","required":true,"description":"Snapshot name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshot status","args":{"repository":"s3-backup","snapshot":"daily-2026-06-01"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.16","content_hash":"sha256:c31f42f0cfa37a2b24165813ca78988693f671ee1026e3c601af57c19991bb48","tarball_url":"https://registry.emisar.dev/v1/packs/elasticsearch/0.1.16/c31f42f0cfa37a2b24165813ca78988693f671ee1026e3c601af57c19991bb48/pack.tar.gz","actions":[{"id":"es.cache_clear","title":"POST /<index>/_cache/clear","summary":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","description":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","kind":"exec","risk":"high","side_effects":["Drops cached data for the index.","Subsequent queries slow until caches re-warm."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Clear caches for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_cache/clear?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.cat_aliases","title":"GET /_cat/aliases","summary":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","description":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Aliases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/aliases?v\""]}},{"id":"es.cat_indices","title":"GET /_cat/indices","summary":"List every index with its primary count, doc count, store size. Sorted by size descending.","description":"List every index with its primary count, doc count, store size. Sorted by size descending.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All indices","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/indices?v&s=store.size:desc\""]}},{"id":"es.cat_nodes","title":"GET /_cat/nodes","summary":"List nodes with heap, RAM, CPU, load, role. Read-only.","description":"List nodes with heap, RAM, CPU, load, role. Read-only.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/nodes?v\""]}},{"id":"es.cat_recovery","title":"GET /_cat/recovery","summary":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","description":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Active recoveries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/recovery?active_only=true&v\""]}},{"id":"es.cat_segments","title":"GET /_cat/segments","summary":"Show per-segment doc + bytes counts. Use to plan a force_merge.","description":"Show per-segment doc + bytes counts. Use to plan a force_merge.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Segments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/segments?v\""]}},{"id":"es.cat_shards","title":"GET /_cat/shards","summary":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","description":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All shards","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/shards?v&s=store:desc\""]}},{"id":"es.cat_thread_pool","title":"GET /_cat/thread_pool","summary":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","description":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Thread pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/thread_pool?v\""]}},{"id":"es.close_index","title":"POST /<index>/_close","summary":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","description":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","kind":"exec","risk":"critical","side_effects":["Index becomes read-only AND unsearchable.","All in-flight requests against it fail.","Reverse with `_open` (not part of this pack)."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Close one index","args":{"index":"logs-2025-12-31"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_close?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.cluster_allocation_explain","title":"POST /_cluster/allocation/explain","summary":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","description":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","kind":"exec","risk":"low","side_effects":["One POST request.","Read-only."],"args":[],"examples":[{"title":"Why is a shard unassigned?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XGET \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/allocation/explain?pretty\""]}},{"id":"es.cluster_health","title":"GET /_cluster/health","summary":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","description":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/health?pretty\""]}},{"id":"es.cluster_settings","title":"GET /_cluster/settings","summary":"Return persistent + transient cluster-level settings.","description":"Return persistent + transient cluster-level settings.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/settings?include_defaults=false&pretty\""]}},{"id":"es.flush_synced","title":"POST /<index>/_flush (flush index)","summary":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. Plain flush; the synced-flush API (/_flush/synced, sync IDs) was deprecated in 7.6 and removed in ES 8.0 — a normal flush gives the same recovery benefit there.","description":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. Plain flush; the synced-flush API (/_flush/synced, sync IDs) was deprecated in 7.6 and removed in ES 8.0 — a normal flush gives the same recovery benefit there.","kind":"exec","risk":"medium","side_effects":["Brief pause to write segments to disk."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Flush an index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_flush?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.force_merge","title":"POST /<index>/_forcemerge","summary":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","description":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","kind":"exec","risk":"high","side_effects":["Heavy IO + CPU on each node holding shards.","Disk space may spike before reclaiming."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"max_segments","type":"integer","required":false,"default":1,"description":"Target segment count per shard.","validation":{"min":1,"max":100}}],"examples":[{"title":"Force-merge yesterday's logs","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_forcemerge?max_num_segments={{ args.max_segments }}&pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_count","title":"GET /<index>/_count","summary":"Return the document count for one index.","description":"Return the document count for one index.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Doc count","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_count?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_mapping","title":"GET /<index>/_mapping","summary":"Return the field mappings for one index.","description":"Return the field mappings for one index.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Mapping for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_mapping?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_settings","title":"GET /<index>/_settings","summary":"Return one index's settings.","description":"Return one index's settings.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Settings for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_settings?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_stats","title":"GET /<index>/_stats","summary":"Show index-level stats — docs, store, indexing/search rates, fielddata.","description":"Show index-level stats — docs, store, indexing/search rates, fielddata.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Stats for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_stats?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.pending_tasks","title":"GET /_cluster/pending_tasks","summary":"List pending master tasks. A growing queue here means the master can't keep up.","description":"List pending master tasks. A growing queue here means the master can't keep up.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Pending master tasks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/pending_tasks\""]}},{"id":"es.snapshot_list","title":"GET /_snapshot/<repo>/_all","summary":"List snapshots in one repository.","description":"List snapshots in one repository.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Snapshot repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshots in 's3-backup'","args":{"repository":"s3-backup"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_snapshot/${1}/_all?pretty\"","emisar","{{ args.repository }}"]}},{"id":"es.snapshot_status","title":"GET /_snapshot/<repo>/<snap>/_status","summary":"Return the in-progress (or completed) status of one snapshot.","description":"Return the in-progress (or completed) status of one snapshot.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"snapshot","type":"string","required":true,"description":"Snapshot name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshot status","args":{"repository":"s3-backup","snapshot":"daily-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_snapshot/${1}/${2}/_status?pretty\"","emisar","{{ args.repository }}","{{ args.snapshot }}"]}}]},{"version":"0.1.13","content_hash":"sha256:a348a29f23240e4dd020f6c3a54c1217968f25be0bf36020cc30106f4c5f6ef9","tarball_url":"https://registry.emisar.dev/v1/packs/elasticsearch/0.1.13/a348a29f23240e4dd020f6c3a54c1217968f25be0bf36020cc30106f4c5f6ef9/pack.tar.gz","actions":[{"id":"es.cache_clear","title":"POST /<index>/_cache/clear","summary":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","description":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","kind":"exec","risk":"high","side_effects":["Drops cached data for the index.","Subsequent queries slow until caches re-warm."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Clear caches for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_cache/clear?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.cat_aliases","title":"GET /_cat/aliases","summary":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","description":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Aliases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/aliases?v\""]}},{"id":"es.cat_indices","title":"GET /_cat/indices","summary":"List every index with its primary count, doc count, store size. Sorted by size descending.","description":"List every index with its primary count, doc count, store size. Sorted by size descending.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All indices","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/indices?v&s=store.size:desc\""]}},{"id":"es.cat_nodes","title":"GET /_cat/nodes","summary":"List nodes with heap, RAM, CPU, load, role. Read-only.","description":"List nodes with heap, RAM, CPU, load, role. Read-only.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/nodes?v\""]}},{"id":"es.cat_recovery","title":"GET /_cat/recovery","summary":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","description":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Active recoveries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/recovery?active_only=true&v\""]}},{"id":"es.cat_segments","title":"GET /_cat/segments","summary":"Show per-segment doc + bytes counts. Use to plan a force_merge.","description":"Show per-segment doc + bytes counts. Use to plan a force_merge.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Segments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/segments?v\""]}},{"id":"es.cat_shards","title":"GET /_cat/shards","summary":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","description":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All shards","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/shards?v&s=store:desc\""]}},{"id":"es.cat_thread_pool","title":"GET /_cat/thread_pool","summary":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","description":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Thread pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/thread_pool?v\""]}},{"id":"es.close_index","title":"POST /<index>/_close","summary":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","description":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","kind":"exec","risk":"critical","side_effects":["Index becomes read-only AND unsearchable.","All in-flight requests against it fail.","Reverse with `_open` (not part of this pack)."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Close one index","args":{"index":"logs-2025-12-31"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_close?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.cluster_allocation_explain","title":"POST /_cluster/allocation/explain","summary":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","description":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","kind":"exec","risk":"low","side_effects":["One POST request.","Read-only."],"args":[],"examples":[{"title":"Why is a shard unassigned?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XGET \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/allocation/explain?pretty\""]}},{"id":"es.cluster_health","title":"GET /_cluster/health","summary":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","description":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/health?pretty\""]}},{"id":"es.cluster_settings","title":"GET /_cluster/settings","summary":"Return persistent + transient cluster-level settings.","description":"Return persistent + transient cluster-level settings.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/settings?include_defaults=false&pretty\""]}},{"id":"es.flush_synced","title":"POST /<index>/_flush (flush index)","summary":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. Plain flush; the synced-flush API (/_flush/synced, sync IDs) was deprecated in 7.6 and removed in ES 8.0 — a normal flush gives the same recovery benefit there.","description":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. Plain flush; the synced-flush API (/_flush/synced, sync IDs) was deprecated in 7.6 and removed in ES 8.0 — a normal flush gives the same recovery benefit there.","kind":"exec","risk":"medium","side_effects":["Brief pause to write segments to disk."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Flush an index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_flush?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.force_merge","title":"POST /<index>/_forcemerge","summary":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","description":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","kind":"exec","risk":"high","side_effects":["Heavy IO + CPU on each node holding shards.","Disk space may spike before reclaiming."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"max_segments","type":"integer","required":false,"default":1,"description":"Target segment count per shard.","validation":{"min":1,"max":100}}],"examples":[{"title":"Force-merge yesterday's logs","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_forcemerge?max_num_segments={{ args.max_segments }}&pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_count","title":"GET /<index>/_count","summary":"Return the document count for one index.","description":"Return the document count for one index.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Doc count","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_count?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_mapping","title":"GET /<index>/_mapping","summary":"Return the field mappings for one index.","description":"Return the field mappings for one index.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Mapping for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_mapping?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_settings","title":"GET /<index>/_settings","summary":"Return one index's settings.","description":"Return one index's settings.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Settings for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_settings?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_stats","title":"GET /<index>/_stats","summary":"Show index-level stats — docs, store, indexing/search rates, fielddata.","description":"Show index-level stats — docs, store, indexing/search rates, fielddata.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Stats for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_stats?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.pending_tasks","title":"GET /_cluster/pending_tasks","summary":"List pending master tasks. A growing queue here means the master can't keep up.","description":"List pending master tasks. A growing queue here means the master can't keep up.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Pending master tasks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/pending_tasks\""]}},{"id":"es.snapshot_list","title":"GET /_snapshot/<repo>/_all","summary":"List snapshots in one repository.","description":"List snapshots in one repository.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Snapshot repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshots in 's3-backup'","args":{"repository":"s3-backup"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_snapshot/${1}/_all?pretty\"","emisar","{{ args.repository }}"]}},{"id":"es.snapshot_status","title":"GET /_snapshot/<repo>/<snap>/_status","summary":"Return the in-progress (or completed) status of one snapshot.","description":"Return the in-progress (or completed) status of one snapshot.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"snapshot","type":"string","required":true,"description":"Snapshot name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshot status","args":{"repository":"s3-backup","snapshot":"daily-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS --globoff --proto =http,https -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_snapshot/${1}/${2}/_status?pretty\"","emisar","{{ args.repository }}","{{ args.snapshot }}"]}}]},{"version":"0.1.12","content_hash":"sha256:150a8c122029db9e008e2d3d50e584b772bea29589eb8ffbfa0bf8a1dfd55199","tarball_url":"https://registry.emisar.dev/v1/packs/elasticsearch/0.1.12/150a8c122029db9e008e2d3d50e584b772bea29589eb8ffbfa0bf8a1dfd55199/pack.tar.gz","actions":[{"id":"es.cache_clear","title":"POST /<index>/_cache/clear","summary":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","description":"Clear caches (request, query, fielddata) on one index. Next queries pay the cold-cache cost.","kind":"exec","risk":"high","side_effects":["Drops cached data for the index.","Subsequent queries slow until caches re-warm."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Clear caches for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_cache/clear?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.cat_aliases","title":"GET /_cat/aliases","summary":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","description":"List all aliases pointing to indices. Use to confirm an alias rotation worked.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Aliases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/aliases?v\""]}},{"id":"es.cat_indices","title":"GET /_cat/indices","summary":"List every index with its primary count, doc count, store size. Sorted by size descending.","description":"List every index with its primary count, doc count, store size. Sorted by size descending.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All indices","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/indices?v&s=store.size:desc\""]}},{"id":"es.cat_nodes","title":"GET /_cat/nodes","summary":"List nodes with heap, RAM, CPU, load, role. Read-only.","description":"List nodes with heap, RAM, CPU, load, role. Read-only.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/nodes?v\""]}},{"id":"es.cat_recovery","title":"GET /_cat/recovery","summary":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","description":"List active shard recoveries (peer, snapshot). Use to monitor rebalance progress.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Active recoveries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/recovery?active_only=true&v\""]}},{"id":"es.cat_segments","title":"GET /_cat/segments","summary":"Show per-segment doc + bytes counts. Use to plan a force_merge.","description":"Show per-segment doc + bytes counts. Use to plan a force_merge.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Segments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/segments?v\""]}},{"id":"es.cat_shards","title":"GET /_cat/shards","summary":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","description":"List every shard with state (STARTED/UNASSIGNED/INITIALIZING/RELOCATING) and node. Sorted by store size.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All shards","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/shards?v&s=store:desc\""]}},{"id":"es.cat_thread_pool","title":"GET /_cat/thread_pool","summary":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","description":"Show per-node thread pool queue + rejection counts. Use to spot search/write thread saturation.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Thread pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cat/thread_pool?v\""]}},{"id":"es.close_index","title":"POST /<index>/_close","summary":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","description":"Close one index — it becomes unsearchable and unwritable, but stays on disk. Use to \"archive\" old logs without deleting. Reverse with /_open. **Closed indices count against shard limits in some versions.**","kind":"exec","risk":"critical","side_effects":["Index becomes read-only AND unsearchable.","All in-flight requests against it fail.","Reverse with `_open` (not part of this pack)."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Close one index","args":{"index":"logs-2025-12-31"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_close?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.cluster_allocation_explain","title":"POST /_cluster/allocation/explain","summary":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","description":"Explain why an unassigned shard hasn't been placed. The canonical \"why is my cluster yellow?\" answer.","kind":"exec","risk":"low","side_effects":["One POST request.","Read-only."],"args":[],"examples":[{"title":"Why is a shard unassigned?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- -XGET \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/allocation/explain?pretty\""]}},{"id":"es.cluster_health","title":"GET /_cluster/health","summary":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","description":"Show cluster status (green/yellow/red), node count, shard counts. Read-only.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster health","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/health?pretty\""]}},{"id":"es.cluster_settings","title":"GET /_cluster/settings","summary":"Return persistent + transient cluster-level settings.","description":"Return persistent + transient cluster-level settings.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Cluster settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/settings?include_defaults=false&pretty\""]}},{"id":"es.flush_synced","title":"POST /<index>/_flush (flush index)","summary":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. Plain flush; the synced-flush API (/_flush/synced, sync IDs) was deprecated in 7.6 and removed in ES 8.0 — a normal flush gives the same recovery benefit there.","description":"Flush the index — forces a Lucene commit so the translog is cleared, which speeds recovery if a shard later restarts. Plain flush; the synced-flush API (/_flush/synced, sync IDs) was deprecated in 7.6 and removed in ES 8.0 — a normal flush gives the same recovery benefit there.","kind":"exec","risk":"medium","side_effects":["Brief pause to write segments to disk."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Flush an index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_flush?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.force_merge","title":"POST /<index>/_forcemerge","summary":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","description":"Merge segments down to `max_num_segments`. Expensive — heavy disk + CPU for the duration. Use on read-only indices (e.g., yesterday's logs) only.","kind":"exec","risk":"high","side_effects":["Heavy IO + CPU on each node holding shards.","Disk space may spike before reclaiming."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"max_segments","type":"integer","required":false,"default":1,"description":"Target segment count per shard.","validation":{"min":1,"max":100}}],"examples":[{"title":"Force-merge yesterday's logs","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- -XPOST \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_forcemerge?max_num_segments={{ args.max_segments }}&pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_count","title":"GET /<index>/_count","summary":"Return the document count for one index.","description":"Return the document count for one index.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Doc count","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_count?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_mapping","title":"GET /<index>/_mapping","summary":"Return the field mappings for one index.","description":"Return the field mappings for one index.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Mapping for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_mapping?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_settings","title":"GET /<index>/_settings","summary":"Return one index's settings.","description":"Return one index's settings.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Settings for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_settings?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.index_stats","title":"GET /<index>/_stats","summary":"Show index-level stats — docs, store, indexing/search rates, fielddata.","description":"Show index-level stats — docs, store, indexing/search rates, fielddata.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Stats for one index","args":{"index":"logs-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/${1}/_stats?pretty\"","emisar","{{ args.index }}"]}},{"id":"es.pending_tasks","title":"GET /_cluster/pending_tasks","summary":"List pending master tasks. A growing queue here means the master can't keep up.","description":"List pending master tasks. A growing queue here means the master can't keep up.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Pending master tasks","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_cluster/pending_tasks\""]}},{"id":"es.snapshot_list","title":"GET /_snapshot/<repo>/_all","summary":"List snapshots in one repository.","description":"List snapshots in one repository.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Snapshot repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshots in 's3-backup'","args":{"repository":"s3-backup"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_snapshot/${1}/_all?pretty\"","emisar","{{ args.repository }}"]}},{"id":"es.snapshot_status","title":"GET /_snapshot/<repo>/<snap>/_status","summary":"Return the in-progress (or completed) status of one snapshot.","description":"Return the in-progress (or completed) status of one snapshot.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[{"name":"repository","type":"string","required":true,"description":"Repository.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"snapshot","type":"string","required":true,"description":"Snapshot name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Snapshot status","args":{"repository":"s3-backup","snapshot":"daily-2026-06-01"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{ printf 'Authorization: Basic '; printf '%s:%s' \"$ELASTIC_USER\" \"$ELASTIC_PASSWORD\" | base64 | tr -d '\\n'; printf '\\n'; } | curl -fsS -H @- \"${ELASTIC_URL:-http://127.0.0.1:9200}/_snapshot/${1}/${2}/_status?pretty\"","emisar","{{ args.repository }}","{{ args.snapshot }}"]}}]}]},{"id":"elixir-beam","name":"Elixir / BEAM runtime","version":"0.1.9","description":"Diagnostics for Elixir and Erlang/BEAM applications on the runner host or inside Docker containers: toolchain versions, EPMD registrations, BEAM OS process state, Linux /proc memory and process-tree detail, release RPC snapshots, supervisor/process/ETS/allocator/scheduler/port introspection, binary-leak checks, and bounded recon_trace call tracing. Releases are discovered from running BEAM processes; target one by release name, or by container for a release inside Docker.","vendor":"emisar","homepage":"https://emisar.dev/packs/elixir-beam","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/elixir-beam","content_hash":"sha256:c74bcf4f1a1a4c018045064fa56bc8f3c6abb4698e0c8eaa9b8d71f3ac47baac","tarball_url":"https://registry.emisar.dev/v1/packs/elixir-beam/0.1.9/c74bcf4f1a1a4c018045064fa56bc8f3c6abb4698e0c8eaa9b8d71f3ac47baac/pack.tar.gz","requires":{"os":["linux"],"binaries":["erl","elixir","epmd","bash"]},"detect":{"binaries":[],"processes":["beam.smp","beam","elixir"],"ports":[]},"setup":{"summary":"Inspects Elixir/Erlang runtime state on the runner host and inside Docker containers. No node cookies or application credentials are needed: release actions go through the release's own bin/RELEASE_NAME control script, discovered from the running BEAM process (start with beam.release_targets).","env":[{"name":"ELIXIR_RELEASE_CTL","description":"Optional override pinning the release control script path, for example `/opt/my_app/bin/my_app` (with a container argument, the path inside the container). Only needed when discovery cannot see the release; add it to the runner's `inherit_env`. The release/container action arguments take precedence."}],"notes":["Release actions discover running releases from BEAM process command lines and only ever execute <release_root>/bin/<release_name> of a release that is already running — callers select among live releases but cannot point actions at arbitrary binaries.","When several releases run on one target, pass the release argument (names come from beam.release_targets). For a release inside Docker, pass the container argument.","Release RPC actions execute fixed, pack-authored expressions only; callers cannot supply arbitrary Elixir code.","If the release control script evaluates runtime config during rpc, the runner service must inherit the same runtime env the release script needs, or those actions will fail before connecting. With the container argument this usually just works: docker exec runs with the container's configured environment.","beam.release_pid reports the PID inside the container's namespace when container is set, not the host PID (find the host PID with beam.processes).","The recon-powered actions (allocators, binary_leak, scheduler_usage, recon_trace) need recon compiled into the release and fail with a clear message otherwise; check with beam.release_debug_tools. The recon_trace action is high-risk because tracing adds runtime overhead and can expose function arguments or return values when explicitly enabled.","There is deliberately no action launching the interactive observer_cli TUI; its dashboards are covered by the release_* snapshot actions (top_processes, ets_tables, allocators, scheduler_usage, ports, memory)."],"host_access":[{"actions":["beam.process_status","beam.process_limits","beam.process_memory","beam.process_tree","beam.release_targets","beam.release_pid","beam.release_runtime","beam.release_memory","beam.release_applications","beam.release_debug_tools","beam.release_registered","beam.release_top_processes","beam.release_process_info","beam.release_supervisor_tree","beam.release_ets_tables","beam.release_allocators","beam.release_binary_leak","beam.release_scheduler_usage","beam.release_ports","beam.recon_trace_calls","beam.recon_trace_clear"],"requirement":"Inspect BEAM processes owned by another user and reach release control scripts or Docker containers.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-elixir-beam-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Release RPC can inspect application state, and root can reach every host process and rootful Docker container."}]}],"verify":"beam.release_targets"},"actions":[{"id":"beam.elixir_version","title":"elixir --version","summary":"Show the installed Elixir and Erlang/OTP versions.","description":"Show the installed Elixir and Erlang/OTP versions.","kind":"exec","risk":"low","side_effects":["One elixir version check.","Read-only."],"args":[],"examples":[{"title":"Elixir version","args":{}}],"search_terms":[],"command":{"binary":"elixir","argv":["--version"]}},{"id":"beam.epmd_names","title":"epmd -names","summary":"List Erlang nodes registered with the local EPMD daemon.","description":"List Erlang nodes registered with the local EPMD daemon.","kind":"exec","risk":"low","side_effects":["One local EPMD query.","Read-only."],"args":[],"examples":[{"title":"Registered local nodes","args":{}}],"search_terms":[],"command":{"binary":"epmd","argv":["-names"]}},{"id":"beam.erl_system_version","title":"Erlang/OTP system version","summary":"Show the installed Erlang/OTP system version.","description":"Show the installed Erlang/OTP system version.","kind":"exec","risk":"low","side_effects":["Starts a short-lived local Erlang VM.","Read-only."],"args":[],"examples":[{"title":"Erlang system version","args":{}}],"search_terms":[],"command":{"binary":"erl","argv":["-noshell","-eval","io:format(\"~s~n\", [erlang:system_info(system_version)]), halt()."]}},{"id":"beam.process_limits","title":"BEAM process limits","summary":"Show Linux resource limits for a BEAM process.","description":"Show Linux resource limits for a BEAM process.","kind":"exec","risk":"low","side_effects":["One /proc limits read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"BEAM OS process PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Limits for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/limits"]}},{"id":"beam.process_memory","title":"BEAM process memory summary","summary":"Show Linux /proc memory, fd, thread, and mapping counts for a BEAM process.","description":"Show Linux /proc memory, fd, thread, and mapping counts for a BEAM process.","kind":"script","risk":"low","side_effects":["Reads selected /proc files for one PID.","Does not read process argv, environment, memory contents, or file descriptor targets.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"BEAM OS process PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Memory summary for PID 4321","args":{"pid":4321}}],"search_terms":[]},{"id":"beam.process_status","title":"BEAM /proc status summary","summary":"Show selected /proc/PID/status fields for a BEAM process.","description":"Show selected /proc/PID/status fields for a BEAM process.","kind":"exec","risk":"low","side_effects":["One /proc status read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"BEAM OS process PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status summary for PID 4321","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","awk '/^(Name|State|Pid|PPid|Uid|Gid|VmPeak|VmSize|VmRSS|Threads|FDSize|voluntary_ctxt_switches|nonvoluntary_ctxt_switches):/ { print }' /proc/{{ args.pid }}/status"]}},{"id":"beam.process_tree","title":"BEAM process tree","summary":"Show ancestors and descendants for a BEAM OS process without command-line arguments.","description":"Show ancestors and descendants for a BEAM OS process without command-line arguments.","kind":"script","risk":"low","side_effects":["Reads the process table.","Does not print command-line arguments or environment variables.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"BEAM OS process PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Tree for PID 4321","args":{"pid":4321}}],"search_terms":[]},{"id":"beam.processes","title":"BEAM process list","summary":"List BEAM and Elixir OS processes on the runner host.","description":"List BEAM and Elixir OS processes on the runner host.","kind":"exec","risk":"low","side_effects":["One process table read without command-line arguments.","Read-only."],"args":[],"examples":[{"title":"Local BEAM processes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ps -eo pid,user,etime,pcpu,pmem,comm | awk 'NR == 1 || $6 ~ /(^|\\/)(beam\\.smp|beam|elixir)$/ { print }' | head -100"]}},{"id":"beam.recon_trace_calls","title":"Bounded recon_trace call capture","summary":"Trace calls to one existing module/function in the running Elixir release for a bounded time window; tracing adds load while active, and the include_args / include_return flags copy raw arguments and returns — routinely secret-bearing — into the recorded output.","description":"Trace calls to one existing module/function in the running Elixir release for a bounded time window; tracing adds load while active, and the include_args / include_return flags copy raw arguments and returns — routinely secret-bearing — into the recorded output.","kind":"script","risk":"high","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","Installs recon_trace call tracing in the running release, then clears it after duration_ms.","Can add runtime overhead while active.","Clears recon_trace state at the end of the capture window.","include_args or include_return prints raw call arguments and return values into the captured output, which is stored in the audit trail and returned to the caller.","Raw BEAM terms routinely carry secrets and PII: a Plug.Conn holds secret_key_base and session data, connection state holds DB and API credentials, and function arguments hold whatever the caller passed.","The runner's always-on redaction only catches secrets in a few text shapes and does not reliably mask BEAM term output. Leave both flags false unless the traced function is known not to touch sensitive data."],"args":[{"name":"module","type":"string","required":true,"description":"Existing module atom to trace, for example MyApp.Worker, Elixir.MyApp.Worker, or gen_server.","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_.@-]{0,127}$","max_length":128}},{"name":"function","type":"string","required":true,"description":"Existing function atom to trace.","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_!?@]{0,127}$","max_length":128}},{"name":"arity","type":"integer","required":true,"description":"Function arity.","validation":{"min":0,"max":255}},{"name":"max_traces","type":"integer","required":false,"default":10,"description":"Maximum trace events to capture.","validation":{"min":1,"max":100}},{"name":"duration_ms","type":"integer","required":false,"default":2000,"description":"Capture window in milliseconds.","validation":{"min":100,"max":10000}},{"name":"pid_scope","type":"string","required":false,"default":"all","description":"Which processes recon_trace should target. Keep the default `all` to catch processes spawned during the window (servers handle each request in a fresh process); `existing` restricts to processes already alive when tracing starts.","validation":{"enum":["existing","new","all"]}},{"name":"include_args","type":"boolean","required":false,"default":false,"description":"Print raw call arguments instead of arity-only call lines. Leaks whatever the callers passed (secrets, PII) into the audit trail; the runner's redaction does not reliably mask BEAM terms. Keep false unless the traced function's arguments are known safe."},{"name":"include_return","type":"boolean","required":false,"default":false,"description":"Print raw return values via recon_trace return tracing. Same exposure as include_args (a returned Plug.Conn carries secret_key_base and session data). Keep false unless the return is known safe."},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Trace arity-only Phoenix endpoint calls for two seconds","args":{"arity":2,"duration_ms":2000,"function":"call","max_traces":10,"module":"MyAppWeb.Endpoint"}},{"title":"Trace a containerized release","args":{"arity":2,"container":"my_app","function":"handle_info","module":"MyApp.Worker"}}],"search_terms":[]},{"id":"beam.recon_trace_clear","title":"Clear recon_trace tracing","summary":"Stop all recon_trace tracing in the running Elixir release.","description":"Stop all recon_trace tracing in the running Elixir release.","kind":"script","risk":"medium","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Mutates tracing state by clearing recon_trace.","Does not modify application data."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Clear recon_trace","args":{}}],"search_terms":[]},{"id":"beam.release_allocators","title":"Elixir release memory allocators","summary":"Show BEAM memory allocator utilization for the running Elixir release with recon_alloc — allocated vs used bytes, the usage ratio, and a per-allocator breakdown for fragmentation analysis. Requires recon in the release (check with beam.release_debug_tools).","description":"Show BEAM memory allocator utilization for the running Elixir release with recon_alloc — allocated vs used bytes, the usage ratio, and a per-allocator breakdown for fragmentation analysis. Requires recon in the release (check with beam.release_debug_tools).","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Allocator utilization","args":{}}],"search_terms":[]},{"id":"beam.release_applications","title":"Elixir release applications","summary":"List started OTP applications in the running Elixir release.","description":"List started OTP applications in the running Elixir release.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Started applications","args":{}}],"search_terms":[]},{"id":"beam.release_binary_leak","title":"Elixir release binary leak check","summary":"Check the running Elixir release for refc binary leaks with recon bin_leak — garbage-collects every process and reports which freed the most binary references. Requires recon in the release (check with beam.release_debug_tools).","description":"Check the running Elixir release for refc binary leaks with recon bin_leak — garbage-collects every process and reports which freed the most binary references. Requires recon in the release (check with beam.release_debug_tools).","kind":"script","risk":"medium","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","Forces a garbage collection of every process in the release; expect a brief latency impact while it runs.","One release rpc call with a fixed expression.","Does not modify application data."],"args":[{"name":"limit","type":"integer","required":false,"default":10,"description":"Number of top binary-releasing processes to report.","validation":{"min":1,"max":100}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Top 10 binary-leak suspects","args":{}}],"search_terms":["memory not dropping"]},{"id":"beam.release_debug_tools","title":"Elixir release debug tools","summary":"Check whether recon, recon_trace, and observer_cli modules are available in the running release.","description":"Check whether recon, recon_trace, and observer_cli modules are available in the running release.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Debug tool availability","args":{}}],"search_terms":[]},{"id":"beam.release_ets_tables","title":"Elixir release ETS tables","summary":"List ETS tables in the running Elixir release sorted by memory or row count, with owner, type, and a total-usage summary.","description":"List ETS tables in the running Elixir release sorted by memory or row count, with owner, type, and a total-usage summary.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Reads table metadata only, never table contents.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum tables to return.","validation":{"min":1,"max":500}},{"name":"sort_by","type":"string","required":false,"default":"memory","description":"Sort tables by memory footprint or row count.","validation":{"enum":["memory","size"]}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Biggest ETS tables by memory","args":{}},{"title":"Biggest tables by row count in a container","args":{"container":"my_app","sort_by":"size"}}],"search_terms":["ets leak","table growing"]},{"id":"beam.release_memory","title":"Elixir release memory snapshot","summary":"Show BEAM memory categories and core counts from the running Elixir release.","description":"Show BEAM memory categories and core counts from the running Elixir release.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Memory snapshot","args":{}}],"search_terms":["memory leak","memory growing"]},{"id":"beam.release_pid","title":"Elixir release OS PID","summary":"Show the OS PID of the running Elixir release (the PID inside the container's namespace when container is set).","description":"Show the OS PID of the running Elixir release (the PID inside the container's namespace when container is set).","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release control-script pid command.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Release PID","args":{}},{"title":"Release PID inside a container","args":{"container":"my_app"}}],"search_terms":[]},{"id":"beam.release_ports","title":"Elixir release BEAM ports","summary":"Count open BEAM ports in the running Elixir release by driver, with the port limit — spot socket or port leaks at a glance.","description":"Count open BEAM ports in the running Elixir release by driver, with the port limit — spot socket or port leaks at a glance.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Port counts by driver","args":{}}],"search_terms":[]},{"id":"beam.release_process_info","title":"Elixir release process info","summary":"Show selected process_info fields for one BEAM PID in the running release.","description":"Show selected process_info fields for one BEAM PID in the running release.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Does not read process dictionaries or mailbox contents.","Read-only."],"args":[{"name":"erlang_pid","type":"string","required":true,"description":"BEAM PID in <A.B.C> form.","validation":{"pattern":"^<[0-9]+\\.[0-9]+\\.[0-9]+>$","max_length":32}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Process info for PID <0.123.0>","args":{"erlang_pid":"<0.123.0>"}}],"search_terms":[]},{"id":"beam.release_registered","title":"Elixir release registered processes","summary":"List registered processes in the running Elixir release with lightweight process info.","description":"List registered processes in the running Elixir release with lightweight process info.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Does not read process dictionaries or mailbox contents.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum registered processes to return.","validation":{"min":1,"max":500}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"First 100 registered processes","args":{}}],"search_terms":[]},{"id":"beam.release_runtime","title":"Elixir release runtime snapshot","summary":"Show a BEAM runtime snapshot from the running Elixir release.","description":"Show a BEAM runtime snapshot from the running Elixir release.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Runtime snapshot","args":{}},{"title":"Runtime snapshot of a containerized release","args":{"container":"my_app"}}],"search_terms":[]},{"id":"beam.release_scheduler_usage","title":"Elixir release scheduler usage","summary":"Show per-scheduler utilization of the running Elixir release sampled over a bounded window with recon scheduler_usage — the accurate BEAM CPU picture, unlike OS-level CPU of busy-waiting schedulers. Requires recon in the release (check with beam.release_debug_tools).","description":"Show per-scheduler utilization of the running Elixir release sampled over a bounded window with recon scheduler_usage — the accurate BEAM CPU picture, unlike OS-level CPU of busy-waiting schedulers. Requires recon in the release (check with beam.release_debug_tools).","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression that samples scheduler wall time for sample_ms.","Read-only."],"args":[{"name":"sample_ms","type":"integer","required":false,"default":1000,"description":"Sampling window in milliseconds.","validation":{"min":100,"max":5000}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"One-second scheduler sample","args":{}}],"search_terms":["high cpu","cpu pegged"]},{"id":"beam.release_supervisor_tree","title":"Elixir release supervisor tree","summary":"Show a bounded supervisor subtree from the running Elixir release.","description":"Show a bounded supervisor subtree from the running Elixir release.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Uses existing atoms only; unknown names do not create atoms.","Read-only."],"args":[{"name":"registered_name","type":"string","required":true,"description":"Registered supervisor name, for example MyApp.Supervisor or Elixir.MyApp.Supervisor.","validation":{"pattern":"^[A-Za-z_][A-Za-z0-9_.@-]{0,127}$","max_length":128}},{"name":"depth","type":"integer","required":false,"default":2,"description":"Maximum supervisor depth to walk.","validation":{"min":0,"max":5}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Top-level supervisor","args":{"depth":2,"registered_name":"MyApp.Supervisor"}}],"search_terms":[]},{"id":"beam.release_targets","title":"Debuggable Elixir releases","summary":"List running Elixir releases on the runner host and inside running Docker containers, with the release and container values to pass to the other beam.release_* actions.","description":"List running Elixir releases on the runner host and inside running Docker containers, with the release and container values to pass to the other beam.release_* actions.","kind":"script","risk":"low","side_effects":["Scans /proc for BEAM processes started from a release.","Probes each running container with docker exec when the docker CLI is available (skipped otherwise).","Read-only."],"args":[{"name":"container","type":"string","required":false,"default":"","description":"Limit the scan to one Docker container name or ID; omit to scan the host and all running containers.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}}],"examples":[{"title":"All debuggable releases","args":{}},{"title":"Releases inside one container","args":{"container":"my_app"}}],"search_terms":[]},{"id":"beam.release_top_processes","title":"Elixir release top BEAM processes","summary":"List top BEAM processes in the running release by memory, mailbox length, reductions, or heap size.","description":"List top BEAM processes in the running release by memory, mailbox length, reductions, or heap size.","kind":"script","risk":"low","side_effects":["Resolves the target release from running BEAM processes (reads /proc; docker exec when container is set).","One release rpc call with a fixed expression.","Does not read process dictionaries or mailbox contents.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":25,"description":"Maximum processes to return.","validation":{"min":1,"max":100}},{"name":"sort_by","type":"string","required":false,"default":"memory","description":"Process metric to sort by.","validation":{"enum":["memory","message_queue_len","reductions","total_heap_size"]}},{"name":"container","type":"string","required":false,"default":"","description":"Docker container name or ID when the release runs inside a container (see beam.release_targets); omit for a release running directly on the host.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9_.-]{0,127})?$","max_length":128}},{"name":"release","type":"string","required":false,"default":"","description":"Release name when several Elixir releases run on the target (see beam.release_targets); omit when only one runs or ELIXIR_RELEASE_CTL pins the target.","validation":{"pattern":"^([a-z][a-z0-9_]{0,63})?$","max_length":64}}],"examples":[{"title":"Top processes by memory","args":{"limit":25,"sort_by":"memory"}},{"title":"Top processes by mailbox length","args":{"limit":25,"sort_by":"message_queue_len"}}],"search_terms":["message queue backlog","mailbox growing","busiest processes"]}],"retired_below":"0.1.9"},{"id":"envoy","name":"Envoy proxy / service mesh","version":"0.1.19","description":"Envoy admin-API ops: cluster + listener + runtime + config + cert inventory, server info, logging level read/write, plus traffic-shifting mutators (drain listeners, healthcheck fail/ok, reset counters) for planned failovers and incident response. Default admin URL http://127.0.0.1:9901; override via ENVOY_ADMIN env.","vendor":"emisar","homepage":"https://emisar.dev/packs/envoy","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/envoy","content_hash":"sha256:98b678a1c317c7d5973a6929ab0c3ea4ca9eee6e8805c8b64ee5579b75fb8c21","tarball_url":"https://registry.emisar.dev/v1/packs/envoy/0.1.19/98b678a1c317c7d5973a6929ab0c3ea4ca9eee6e8805c8b64ee5579b75fb8c21/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["envoy"],"ports":[9901]},"setup":{"summary":"Operates on the local Envoy instance on the runner host via its admin endpoint (default 127.0.0.1:9901) — no credentials needed.","env":[{"name":"ENVOY_ADMIN","description":"Base URL of the Envoy admin endpoint for the read actions; set only if it is not on the default.","default":"http://127.0.0.1:9901"}],"notes":["`ENVOY_ADMIN` only reaches an action when the runner allowlists it in `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default. Unset, it falls back to http://127.0.0.1:9901, so an admin interface on another port or host silently reads the local one instead.","The admin endpoint must be enabled in the Envoy bootstrap (admin.address) for any action to work.","The traffic-shifting mutators (drain_listeners, healthcheck_fail/ok, reset_counters) take their admin URL as an `admin` argument, not from `ENVOY_ADMIN`."],"verify":"envoy.ready"},"actions":[{"id":"envoy.certs","title":"GET /certs","summary":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","description":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Certs","args":{}}],"search_terms":["expired"],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/certs\""]}},{"id":"envoy.clusters","title":"GET /clusters","summary":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","description":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Clusters + endpoints","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/clusters\""]}},{"id":"envoy.config_dump","title":"GET /config_dump","summary":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full xDS config (may include secrets)."],"args":[],"examples":[{"title":"Full config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/config_dump?include_eds=true\""]}},{"id":"envoy.drain_listeners","title":"POST /drain_listeners","summary":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","description":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","kind":"exec","risk":"high","side_effects":["All listeners stop accepting new connections.","Existing connections drain over the configured grace.","Health checks may fail externally during drain."],"args":[{"name":"admin","type":"string","required":false,"default":"http://127.0.0.1:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"inboundonly","type":"boolean","required":false,"default":false,"description":"Drain only inbound listeners."}],"examples":[{"title":"Drain inbound listeners","args":{"inboundonly":true}}],"search_terms":["graceful shutdown"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.inboundonly }}' = 'true' ]; then curl -q -sSf --globoff --proto =http,https -X POST ''\"$1\"'/drain_listeners?inboundonly'; else curl -q -sSf --globoff --proto =http,https -X POST ''\"$1\"'/drain_listeners'; fi","emisar","{{ args.admin }}"]}},{"id":"envoy.healthcheck_fail","title":"POST /healthcheck/fail","summary":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","description":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","kind":"exec","risk":"high","side_effects":["Envoy reports unhealthy on /healthcheck.","Upstream LB removes this instance from rotation.","Existing connections continue until they close."],"args":[{"name":"admin","type":"string","required":false,"default":"http://127.0.0.1:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Take instance out of rotation","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/fail"]}},{"id":"envoy.healthcheck_ok","title":"POST /healthcheck/ok","summary":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","description":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","kind":"exec","risk":"medium","side_effects":["Envoy reports healthy on /healthcheck.","Upstream LB begins routing traffic back."],"args":[{"name":"admin","type":"string","required":false,"default":"http://127.0.0.1:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Return instance to rotation","args":{}}],"search_terms":["back into rotation"],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/ok"]}},{"id":"envoy.listeners","title":"GET /listeners","summary":"List all active listeners with bind address.","description":"List all active listeners with bind address.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Listeners","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/listeners\""]}},{"id":"envoy.logging_get","title":"POST /logging","summary":"Show current per-component log levels.","description":"Show current per-component log levels.","kind":"exec","risk":"low","side_effects":["One admin POST without mutation parameters.","Read-only."],"args":[],"examples":[{"title":"Logging","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https -X POST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging\""]}},{"id":"envoy.logging_set","title":"POST /logging?level=<level>","summary":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","description":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","kind":"exec","risk":"medium","side_effects":["All components switch to the new level.","Log volume can spike at debug/trace."],"args":[{"name":"level","type":"string","required":true,"description":"Log level.","validation":{"enum":["trace","debug","info","warning","error","critical","off"]}}],"examples":[{"title":"Set debug","args":{"level":"debug"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https -XPOST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging?level={{ args.level }}\""]}},{"id":"envoy.ready","title":"GET /ready","summary":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","description":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Ready?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https -o /dev/null -w '%{http_code}\\n' \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/ready\""]}},{"id":"envoy.reset_counters","title":"POST /reset_counters","summary":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","description":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","kind":"exec","risk":"medium","side_effects":["All Envoy counters zero.","Histograms and gauges unaffected.","In-flight diagnostics referencing old counter values lose context."],"args":[{"name":"admin","type":"string","required":false,"default":"http://127.0.0.1:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reset stats","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/reset_counters"]}},{"id":"envoy.runtime","title":"GET /runtime","summary":"Show runtime overrides (feature flags + numeric overrides).","description":"Show runtime overrides (feature flags + numeric overrides).","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Runtime overrides","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/runtime\""]}},{"id":"envoy.server_info","title":"GET /server_info","summary":"Show Envoy version, uptime, hot-restart state, command-line.","description":"Show Envoy version, uptime, hot-restart state, command-line.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Server info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/server_info\""]}},{"id":"envoy.stats","title":"GET /stats (filter)","summary":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","description":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"filter","type":"string","required":false,"default":"cluster|listener|server","description":"Regex filter passed to ?filter=.","validation":{"pattern":"^[a-zA-Z0-9_.|*\\-]{1,128}$"}}],"examples":[{"title":"Cluster stats","args":{"filter":"cluster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/stats?filter=${1}\"","emisar","{{ args.filter }}"]}}],"previous_versions":[{"version":"0.1.17","content_hash":"sha256:c05aa7185defadc5236a8ee326d62b75dd2c4e188d662a7204edcae05814f282","tarball_url":"https://registry.emisar.dev/v1/packs/envoy/0.1.17/c05aa7185defadc5236a8ee326d62b75dd2c4e188d662a7204edcae05814f282/pack.tar.gz","actions":[{"id":"envoy.certs","title":"GET /certs","summary":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","description":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Certs","args":{}}],"search_terms":["expired"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/certs\""]}},{"id":"envoy.clusters","title":"GET /clusters","summary":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","description":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Clusters + endpoints","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/clusters\""]}},{"id":"envoy.config_dump","title":"GET /config_dump","summary":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full xDS config (may include secrets)."],"args":[],"examples":[{"title":"Full config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/config_dump?include_eds=true\""]}},{"id":"envoy.drain_listeners","title":"POST /drain_listeners","summary":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","description":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","kind":"exec","risk":"high","side_effects":["All listeners stop accepting new connections.","Existing connections drain over the configured grace.","Health checks may fail externally during drain."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"inboundonly","type":"boolean","required":false,"default":false,"description":"Drain only inbound listeners."}],"examples":[{"title":"Drain inbound listeners","args":{"inboundonly":true}}],"search_terms":["graceful shutdown"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.inboundonly }}' = 'true' ]; then curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/drain_listeners?inboundonly'; else curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/drain_listeners'; fi","emisar","{{ args.admin }}"]}},{"id":"envoy.healthcheck_fail","title":"POST /healthcheck/fail","summary":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","description":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","kind":"exec","risk":"high","side_effects":["Envoy reports unhealthy on /healthcheck.","Upstream LB removes this instance from rotation.","Existing connections continue until they close."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Take instance out of rotation","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/fail"]}},{"id":"envoy.healthcheck_ok","title":"POST /healthcheck/ok","summary":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","description":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","kind":"exec","risk":"medium","side_effects":["Envoy reports healthy on /healthcheck.","Upstream LB begins routing traffic back."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Return instance to rotation","args":{}}],"search_terms":["back into rotation"],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/ok"]}},{"id":"envoy.listeners","title":"GET /listeners","summary":"List all active listeners with bind address.","description":"List all active listeners with bind address.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Listeners","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/listeners\""]}},{"id":"envoy.logging_get","title":"POST /logging","summary":"Show current per-component log levels.","description":"Show current per-component log levels.","kind":"exec","risk":"low","side_effects":["One admin POST without mutation parameters.","Read-only."],"args":[],"examples":[{"title":"Logging","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging\""]}},{"id":"envoy.logging_set","title":"POST /logging?level=<level>","summary":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","description":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","kind":"exec","risk":"medium","side_effects":["All components switch to the new level.","Log volume can spike at debug/trace."],"args":[{"name":"level","type":"string","required":true,"description":"Log level.","validation":{"enum":["trace","debug","info","warning","error","critical","off"]}}],"examples":[{"title":"Set debug","args":{"level":"debug"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -XPOST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging?level={{ args.level }}\""]}},{"id":"envoy.ready","title":"GET /ready","summary":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","description":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Ready?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -o /dev/null -w '%{http_code}\\n' \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/ready\""]}},{"id":"envoy.reset_counters","title":"POST /reset_counters","summary":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","description":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","kind":"exec","risk":"medium","side_effects":["All Envoy counters zero.","Histograms and gauges unaffected.","In-flight diagnostics referencing old counter values lose context."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reset stats","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/reset_counters"]}},{"id":"envoy.runtime","title":"GET /runtime","summary":"Show runtime overrides (feature flags + numeric overrides).","description":"Show runtime overrides (feature flags + numeric overrides).","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Runtime overrides","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/runtime\""]}},{"id":"envoy.server_info","title":"GET /server_info","summary":"Show Envoy version, uptime, hot-restart state, command-line.","description":"Show Envoy version, uptime, hot-restart state, command-line.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Server info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/server_info\""]}},{"id":"envoy.stats","title":"GET /stats (filter)","summary":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","description":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"filter","type":"string","required":false,"default":"cluster|listener|server","description":"Regex filter passed to ?filter=.","validation":{"pattern":"^[a-zA-Z0-9_.|*\\-]{1,128}$"}}],"examples":[{"title":"Cluster stats","args":{"filter":"cluster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/stats?filter=${1}\"","emisar","{{ args.filter }}"]}}]},{"version":"0.1.15","content_hash":"sha256:eb34da4aaba6675cdded10f451e0722b29a6443192b54e6095fe73e3f7a2c408","tarball_url":"https://registry.emisar.dev/v1/packs/envoy/0.1.15/eb34da4aaba6675cdded10f451e0722b29a6443192b54e6095fe73e3f7a2c408/pack.tar.gz","actions":[{"id":"envoy.certs","title":"GET /certs","summary":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","description":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Certs","args":{}}],"search_terms":["expired"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/certs\""]}},{"id":"envoy.clusters","title":"GET /clusters","summary":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","description":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Clusters + endpoints","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/clusters\""]}},{"id":"envoy.config_dump","title":"GET /config_dump","summary":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full xDS config (may include secrets)."],"args":[],"examples":[{"title":"Full config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/config_dump?include_eds=true\""]}},{"id":"envoy.drain_listeners","title":"POST /drain_listeners","summary":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","description":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","kind":"exec","risk":"high","side_effects":["All listeners stop accepting new connections.","Existing connections drain over the configured grace.","Health checks may fail externally during drain."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"inboundonly","type":"boolean","required":false,"default":false,"description":"Drain only inbound listeners."}],"examples":[{"title":"Drain inbound listeners","args":{"inboundonly":true}}],"search_terms":["graceful shutdown"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.inboundonly }}' = 'true' ]; then curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/drain_listeners?inboundonly'; else curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/drain_listeners'; fi","emisar","{{ args.admin }}"]}},{"id":"envoy.healthcheck_fail","title":"POST /healthcheck/fail","summary":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","description":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","kind":"exec","risk":"high","side_effects":["Envoy reports unhealthy on /healthcheck.","Upstream LB removes this instance from rotation.","Existing connections continue until they close."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Take instance out of rotation","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/fail"]}},{"id":"envoy.healthcheck_ok","title":"POST /healthcheck/ok","summary":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","description":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","kind":"exec","risk":"medium","side_effects":["Envoy reports healthy on /healthcheck.","Upstream LB begins routing traffic back."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Return instance to rotation","args":{}}],"search_terms":["back into rotation"],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/ok"]}},{"id":"envoy.listeners","title":"GET /listeners","summary":"List all active listeners with bind address.","description":"List all active listeners with bind address.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Listeners","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/listeners\""]}},{"id":"envoy.logging_get","title":"POST /logging","summary":"Show current per-component log levels.","description":"Show current per-component log levels.","kind":"exec","risk":"low","side_effects":["One admin POST without mutation parameters.","Read-only."],"args":[],"examples":[{"title":"Logging","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging\""]}},{"id":"envoy.logging_set","title":"POST /logging?level=<level>","summary":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","description":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","kind":"exec","risk":"medium","side_effects":["All components switch to the new level.","Log volume can spike at debug/trace."],"args":[{"name":"level","type":"string","required":true,"description":"Log level.","validation":{"enum":["trace","debug","info","warning","error","critical","off"]}}],"examples":[{"title":"Set debug","args":{"level":"debug"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -XPOST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging?level={{ args.level }}\""]}},{"id":"envoy.ready","title":"GET /ready","summary":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","description":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Ready?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -o /dev/null -w '%{http_code}\\n' \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/ready\""]}},{"id":"envoy.reset_counters","title":"POST /reset_counters","summary":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","description":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","kind":"exec","risk":"medium","side_effects":["All Envoy counters zero.","Histograms and gauges unaffected.","In-flight diagnostics referencing old counter values lose context."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reset stats","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/reset_counters"]}},{"id":"envoy.runtime","title":"GET /runtime","summary":"Show runtime overrides (feature flags + numeric overrides).","description":"Show runtime overrides (feature flags + numeric overrides).","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Runtime overrides","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/runtime\""]}},{"id":"envoy.server_info","title":"GET /server_info","summary":"Show Envoy version, uptime, hot-restart state, command-line.","description":"Show Envoy version, uptime, hot-restart state, command-line.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Server info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/server_info\""]}},{"id":"envoy.stats","title":"GET /stats (filter)","summary":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","description":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"filter","type":"string","required":false,"default":"cluster|listener|server","description":"Regex filter passed to ?filter=.","validation":{"pattern":"^[a-zA-Z0-9_.|*\\-]{1,128}$"}}],"examples":[{"title":"Cluster stats","args":{"filter":"cluster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/stats?filter=${1}\"","emisar","{{ args.filter }}"]}}]},{"version":"0.1.14","content_hash":"sha256:a7f00a5bbc2b4b08cb6785b2e9fc9f727a4b0e5cfddf1c9a882e69778284ca19","tarball_url":"https://registry.emisar.dev/v1/packs/envoy/0.1.14/a7f00a5bbc2b4b08cb6785b2e9fc9f727a4b0e5cfddf1c9a882e69778284ca19/pack.tar.gz","actions":[{"id":"envoy.certs","title":"GET /certs","summary":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","description":"List active TLS certs known to Envoy — subjects, expiry, days remaining.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Certs","args":{}}],"search_terms":["expired"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/certs\""]}},{"id":"envoy.clusters","title":"GET /clusters","summary":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","description":"List all clusters with endpoint health + stats. Use for \"which upstream is unhealthy?\".","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Clusters + endpoints","args":{}}],"search_terms":["backend down","dead backend"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/clusters\""]}},{"id":"envoy.config_dump","title":"GET /config_dump","summary":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump full xDS config — bootstrap, clusters, routes, listeners. This surfaces the entire effective config, which can carry secrets (TLS private keys / SDS material, upstream credentials, auth headers). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One admin GET.","Read-only, but exposes the full xDS config (may include secrets)."],"args":[],"examples":[{"title":"Full config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/config_dump?include_eds=true\""]}},{"id":"envoy.drain_listeners","title":"POST /drain_listeners","summary":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","description":"Mark all listeners as draining. Existing connections close on their own as requests complete; no new connections accepted on drained listeners. Use during a planned restart to drain traffic before flipping a load balancer.","kind":"exec","risk":"high","side_effects":["All listeners stop accepting new connections.","Existing connections drain over the configured grace.","Health checks may fail externally during drain."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"inboundonly","type":"boolean","required":false,"default":false,"description":"Drain only inbound listeners."}],"examples":[{"title":"Drain inbound listeners","args":{"inboundonly":true}}],"search_terms":["graceful shutdown"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.inboundonly }}' = 'true' ]; then curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/drain_listeners?inboundonly'; else curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/drain_listeners'; fi","emisar","{{ args.admin }}"]}},{"id":"envoy.healthcheck_fail","title":"POST /healthcheck/fail","summary":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","description":"Mark Envoy unhealthy via its admin API. External health checks see failure; load balancer pulls this instance out of rotation. Use during planned maintenance to drain traffic before a restart.","kind":"exec","risk":"high","side_effects":["Envoy reports unhealthy on /healthcheck.","Upstream LB removes this instance from rotation.","Existing connections continue until they close."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Take instance out of rotation","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/fail"]}},{"id":"envoy.healthcheck_ok","title":"POST /healthcheck/ok","summary":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","description":"Mark Envoy healthy again. Reverses healthcheck_fail. Load balancer starts sending traffic again on the next health check.","kind":"exec","risk":"medium","side_effects":["Envoy reports healthy on /healthcheck.","Upstream LB begins routing traffic back."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Return instance to rotation","args":{}}],"search_terms":["back into rotation"],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/healthcheck/ok"]}},{"id":"envoy.listeners","title":"GET /listeners","summary":"List all active listeners with bind address.","description":"List all active listeners with bind address.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Listeners","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/listeners\""]}},{"id":"envoy.logging_get","title":"POST /logging","summary":"Show current per-component log levels.","description":"Show current per-component log levels.","kind":"exec","risk":"low","side_effects":["One admin POST without mutation parameters.","Read-only."],"args":[],"examples":[{"title":"Logging","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging\""]}},{"id":"envoy.logging_set","title":"POST /logging?level=<level>","summary":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","description":"Set all components to one log level. Use \"debug\" for triage, then revert to \"info\".","kind":"exec","risk":"medium","side_effects":["All components switch to the new level.","Log volume can spike at debug/trace."],"args":[{"name":"level","type":"string","required":true,"description":"Log level.","validation":{"enum":["trace","debug","info","warning","error","critical","off"]}}],"examples":[{"title":"Set debug","args":{"level":"debug"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -XPOST \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/logging?level={{ args.level }}\""]}},{"id":"envoy.ready","title":"GET /ready","summary":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","description":"Check readiness — 200 if Envoy is fully initialized; 503 otherwise.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Ready?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -o /dev/null -w '%{http_code}\\n' \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/ready\""]}},{"id":"envoy.reset_counters","title":"POST /reset_counters","summary":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","description":"Reset all Envoy stat counters to zero. Use before isolating a specific test scenario or after diagnosing a noisy historical counter. Histograms and gauges unaffected.","kind":"exec","risk":"medium","side_effects":["All Envoy counters zero.","Histograms and gauges unaffected.","In-flight diagnostics referencing old counter values lose context."],"args":[{"name":"admin","type":"string","required":false,"default":"http://localhost:9901","description":"Envoy admin URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reset stats","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.admin }}/reset_counters"]}},{"id":"envoy.runtime","title":"GET /runtime","summary":"Show runtime overrides (feature flags + numeric overrides).","description":"Show runtime overrides (feature flags + numeric overrides).","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Runtime overrides","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/runtime\""]}},{"id":"envoy.server_info","title":"GET /server_info","summary":"Show Envoy version, uptime, hot-restart state, command-line.","description":"Show Envoy version, uptime, hot-restart state, command-line.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[],"examples":[{"title":"Server info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/server_info\""]}},{"id":"envoy.stats","title":"GET /stats (filter)","summary":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","description":"Show Envoy stats matching a regex filter. Use 'cluster|listener|server' as a sane default.","kind":"exec","risk":"low","side_effects":["One admin GET.","Read-only."],"args":[{"name":"filter","type":"string","required":false,"default":"cluster|listener|server","description":"Regex filter passed to ?filter=.","validation":{"pattern":"^[a-zA-Z0-9_.|*\\-]{1,128}$"}}],"examples":[{"title":"Cluster stats","args":{"filter":"cluster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${ENVOY_ADMIN:-http://127.0.0.1:9901}/stats?filter=${1}\"","emisar","{{ args.filter }}"]}}]}]},{"id":"fail2ban","name":"fail2ban","version":"0.1.11","description":"fail2ban inventory + per-jail banned-IP listings plus operator mutators for incident response: ban an IP into a jail, unban a false positive, reload jail filters from disk.","vendor":"emisar","homepage":"https://emisar.dev/packs/fail2ban","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/fail2ban","content_hash":"sha256:81ba87cf78a6d3868acf724da04a145178c79d91c9da3d65bb1e067cb6a45d2f","tarball_url":"https://registry.emisar.dev/v1/packs/fail2ban/0.1.11/81ba87cf78a6d3868acf724da04a145178c79d91c9da3d65bb1e067cb6a45d2f/pack.tar.gz","requires":{"os":["linux"],"binaries":["fail2ban-client"]},"detect":{"binaries":[],"processes":["fail2ban-server"],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","host_access":[{"actions":["f2b.status","f2b.version","f2b.jail_status","f2b.banned_ips","f2b.unban_ip","f2b.banip","f2b.reload"],"requirement":"Connect to the Fail2ban control socket.","recipes":[{"name":"Debian and Ubuntu — default emisar service user","commands":["sudo apt-get install -y acl","sudo install -d -m 0755 /etc/systemd/system/fail2ban.service.d","printf '%s\\n' '[Service]' \"ExecStartPost=-/usr/bin/timeout 10 /bin/sh -c 'until [ -S /run/fail2ban/fail2ban.sock ]; do sleep 0.1; done; exec /usr/bin/setfacl -m u:emisar:rw /run/fail2ban/fail2ban.sock'\" | sudo tee /etc/systemd/system/fail2ban.service.d/emisar-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart fail2ban"],"verify":["sudo -u emisar fail2ban-client status"],"impact":"Any process running as emisar can control Fail2ban through its socket. Every listed read and mutating action gains that authority. The bounded systemd hook reapplies the ACL whenever Fail2ban recreates the socket; the verification command reports a failed grant without taking Fail2ban down."}]},{"actions":["f2b.log_tail"],"requirement":"Read /var/log/fail2ban.log.","recipes":[{"name":"Debian and Ubuntu — default emisar service user","commands":["sudo usermod -aG adm emisar","sudo systemctl restart emisar"],"verify":["sudo -u emisar test -r /var/log/fail2ban.log"],"impact":"The emisar service identity can read every host log granted to the adm group, not only Fail2ban. The group membership survives Fail2ban log rotation and host restarts."}]}],"verify":"f2b.status"},"actions":[{"id":"f2b.banip","title":"fail2ban-client set <jail> banip <ip>","summary":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","description":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","kind":"exec","risk":"high","side_effects":["IP banned via the jail's configured action.","Existing connections from that IP may be dropped immediately.","Ban duration follows the jail's bantime setting."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Ban an IP from the sshd jail","args":{"ip":"203.0.113.42","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","banip","{{ args.ip }}"]}},{"id":"f2b.banned_ips","title":"get <jail> banip","summary":"List currently banned IPs in one jail.","description":"List currently banned IPs in one jail.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Banned in sshd","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["get","{{ args.jail }}","banip"]}},{"id":"f2b.jail_status","title":"fail2ban-client status <jail>","summary":"Show one jail's filter + actions + currently banned counts.","description":"Show one jail's filter + actions + currently banned counts.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status","{{ args.jail }}"]}},{"id":"f2b.log_tail","title":"tail /var/log/fail2ban.log","summary":"Tail the last N lines of fail2ban.log.","description":"Tail the last N lines of fail2ban.log.","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/fail2ban.log"]}},{"id":"f2b.reload","title":"fail2ban-client reload [jail]","summary":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","description":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","kind":"exec","risk":"medium","side_effects":["Filter + action + jail settings re-read from disk.","Active bans persist across reload."],"args":[{"name":"jail","type":"string","required":false,"default":"","description":"Jail name (empty to reload all).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Reload everything","args":{}},{"title":"Reload sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","fail2ban-client reload \"$1\"","emisar","{{ args.jail }}"]}},{"id":"f2b.status","title":"fail2ban-client status","summary":"List all configured jails + currently-active count.","description":"List all configured jails + currently-active count.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"All jails","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status"]}},{"id":"f2b.unban_ip","title":"set <jail> unbanip <ip>","summary":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","description":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","kind":"exec","risk":"medium","side_effects":["IP removed from the jail's banned set.","Future failures will re-ban according to the jail's policy."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[a-fA-F0-9:.]{2,45}$"}}],"examples":[{"title":"Unban one IP","args":{"ip":"203.0.113.10","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","unbanip","{{ args.ip }}"]}},{"id":"f2b.version","title":"fail2ban-client version","summary":"Show the fail2ban daemon version.","description":"Show the fail2ban daemon version.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["version"]}}],"previous_versions":[{"version":"0.1.8","content_hash":"sha256:185b6fcafc2b311be3732b4dba9f0c90f932196a822277ddc0ad9adaf241fe6a","tarball_url":"https://registry.emisar.dev/v1/packs/fail2ban/0.1.8/185b6fcafc2b311be3732b4dba9f0c90f932196a822277ddc0ad9adaf241fe6a/pack.tar.gz","actions":[{"id":"f2b.banip","title":"fail2ban-client set <jail> banip <ip>","summary":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","description":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","kind":"exec","risk":"high","side_effects":["IP banned via the jail's configured action.","Existing connections from that IP may be dropped immediately.","Ban duration follows the jail's bantime setting."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Ban an IP from the sshd jail","args":{"ip":"203.0.113.42","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","banip","{{ args.ip }}"]}},{"id":"f2b.banned_ips","title":"get <jail> banip","summary":"List currently banned IPs in one jail.","description":"List currently banned IPs in one jail.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Banned in sshd","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["get","{{ args.jail }}","banip"]}},{"id":"f2b.jail_status","title":"fail2ban-client status <jail>","summary":"Show one jail's filter + actions + currently banned counts.","description":"Show one jail's filter + actions + currently banned counts.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status","{{ args.jail }}"]}},{"id":"f2b.log_tail","title":"tail /var/log/fail2ban.log","summary":"Tail the last N lines of fail2ban.log.","description":"Tail the last N lines of fail2ban.log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/fail2ban.log"]}},{"id":"f2b.reload","title":"fail2ban-client reload [jail]","summary":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","description":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","kind":"exec","risk":"medium","side_effects":["Filter + action + jail settings re-read from disk.","Active bans persist across reload."],"args":[{"name":"jail","type":"string","required":false,"default":"","description":"Jail name (empty to reload all).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Reload everything","args":{}},{"title":"Reload sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","fail2ban-client reload \"$1\"","emisar","{{ args.jail }}"]}},{"id":"f2b.status","title":"fail2ban-client status","summary":"List all configured jails + currently-active count.","description":"List all configured jails + currently-active count.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"All jails","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status"]}},{"id":"f2b.unban_ip","title":"set <jail> unbanip <ip>","summary":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","description":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","kind":"exec","risk":"medium","side_effects":["IP removed from the jail's banned set.","Future failures will re-ban according to the jail's policy."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[a-fA-F0-9:.]{2,45}$"}}],"examples":[{"title":"Unban one IP","args":{"ip":"203.0.113.10","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","unbanip","{{ args.ip }}"]}},{"id":"f2b.version","title":"fail2ban-client version","summary":"Show the fail2ban daemon version.","description":"Show the fail2ban daemon version.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["version"]}}]},{"version":"0.1.7","content_hash":"sha256:a79690d64c6c197edba8e50e243d728c33554ec3d5188b0d3bfa39ea2097f878","tarball_url":"https://registry.emisar.dev/v1/packs/fail2ban/0.1.7/a79690d64c6c197edba8e50e243d728c33554ec3d5188b0d3bfa39ea2097f878/pack.tar.gz","actions":[{"id":"f2b.banip","title":"fail2ban-client set <jail> banip <ip>","summary":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","description":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","kind":"exec","risk":"high","side_effects":["IP banned via the jail's configured action.","Existing connections from that IP may be dropped immediately.","Ban duration follows the jail's bantime setting."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Ban an IP from the sshd jail","args":{"ip":"203.0.113.42","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","banip","{{ args.ip }}"]}},{"id":"f2b.banned_ips","title":"get <jail> banip","summary":"List currently banned IPs in one jail.","description":"List currently banned IPs in one jail.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Banned in sshd","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["get","{{ args.jail }}","banip"]}},{"id":"f2b.jail_status","title":"fail2ban-client status <jail>","summary":"Show one jail's filter + actions + currently banned counts.","description":"Show one jail's filter + actions + currently banned counts.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status","{{ args.jail }}"]}},{"id":"f2b.log_tail","title":"tail /var/log/fail2ban.log","summary":"Tail the last N lines of fail2ban.log.","description":"Tail the last N lines of fail2ban.log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/fail2ban.log"]}},{"id":"f2b.reload","title":"fail2ban-client reload [jail]","summary":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","description":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","kind":"exec","risk":"medium","side_effects":["Filter + action + jail settings re-read from disk.","Active bans persist across reload."],"args":[{"name":"jail","type":"string","required":false,"default":"","description":"Jail name (empty to reload all).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Reload everything","args":{}},{"title":"Reload sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","fail2ban-client reload \"$1\"","emisar","{{ args.jail }}"]}},{"id":"f2b.status","title":"fail2ban-client status","summary":"List all configured jails + currently-active count.","description":"List all configured jails + currently-active count.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"All jails","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status"]}},{"id":"f2b.unban_ip","title":"set <jail> unbanip <ip>","summary":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","description":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","kind":"exec","risk":"medium","side_effects":["IP removed from the jail's banned set.","Future failures will re-ban according to the jail's policy."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[a-fA-F0-9:.]{2,45}$"}}],"examples":[{"title":"Unban one IP","args":{"ip":"203.0.113.10","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","unbanip","{{ args.ip }}"]}},{"id":"f2b.version","title":"fail2ban-client version","summary":"Show the fail2ban daemon version.","description":"Show the fail2ban daemon version.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["version"]}}]},{"version":"0.1.6","content_hash":"sha256:754816325b3229335585709e322c64162d12d16b1f336197d690ddcad442032f","tarball_url":"https://registry.emisar.dev/v1/packs/fail2ban/0.1.6/754816325b3229335585709e322c64162d12d16b1f336197d690ddcad442032f/pack.tar.gz","actions":[{"id":"f2b.banip","title":"fail2ban-client set <jail> banip <ip>","summary":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","description":"Add an IP to a jail's banlist manually. Use during an active attack when log-based detection is too slow. Banned IPs hit the configured action (typically iptables DROP).","kind":"exec","risk":"high","side_effects":["IP banned via the jail's configured action.","Existing connections from that IP may be dropped immediately.","Ban duration follows the jail's bantime setting."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Ban an IP from the sshd jail","args":{"ip":"203.0.113.42","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","banip","{{ args.ip }}"]}},{"id":"f2b.banned_ips","title":"get <jail> banip","summary":"List currently banned IPs in one jail.","description":"List currently banned IPs in one jail.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Banned in sshd","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["get","{{ args.jail }}","banip"]}},{"id":"f2b.jail_status","title":"fail2ban-client status <jail>","summary":"Show one jail's filter + actions + currently banned counts.","description":"Show one jail's filter + actions + currently banned counts.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status","{{ args.jail }}"]}},{"id":"f2b.log_tail","title":"tail /var/log/fail2ban.log","summary":"Tail the last N lines of fail2ban.log.","description":"Tail the last N lines of fail2ban.log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","/var/log/fail2ban.log"]}},{"id":"f2b.reload","title":"fail2ban-client reload [jail]","summary":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","description":"Reload fail2ban config. Without a jail, reloads everything. With a jail, reloads that jail only (its filter, action, and settings). Existing bans are preserved.","kind":"exec","risk":"medium","side_effects":["Filter + action + jail settings re-read from disk.","Active bans persist across reload."],"args":[{"name":"jail","type":"string","required":false,"default":"","description":"Jail name (empty to reload all).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Reload everything","args":{}},{"title":"Reload sshd jail","args":{"jail":"sshd"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","fail2ban-client reload {{ args.jail }}"]}},{"id":"f2b.status","title":"fail2ban-client status","summary":"List all configured jails + currently-active count.","description":"List all configured jails + currently-active count.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"All jails","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["status"]}},{"id":"f2b.unban_ip","title":"set <jail> unbanip <ip>","summary":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","description":"Remove one IP's ban from one jail. Counter is reset; IP may be banned again on next failure.","kind":"exec","risk":"medium","side_effects":["IP removed from the jail's banned set.","Future failures will re-ban according to the jail's policy."],"args":[{"name":"jail","type":"string","required":true,"description":"Jail name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[a-fA-F0-9:.]{2,45}$"}}],"examples":[{"title":"Unban one IP","args":{"ip":"203.0.113.10","jail":"sshd"}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["set","{{ args.jail }}","unbanip","{{ args.ip }}"]}},{"id":"f2b.version","title":"fail2ban-client version","summary":"Show the fail2ban daemon version.","description":"Show the fail2ban daemon version.","kind":"exec","risk":"low","side_effects":["One fail2ban call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"fail2ban-client","argv":["version"]}}]}]},{"id":"firewall","name":"Firewall and netfilter","version":"0.1.15","description":"iptables, nftables, conntrack, and traffic-control inspection plus narrow operator actions for incident response (block IP, unblock IP, flush chain). Rule edits are not persisted across iptables service reload — use IaC for permanent rules.","vendor":"emisar","homepage":"https://emisar.dev/packs/firewall","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/firewall","content_hash":"sha256:888107ae1a1fe436c6e067cccf5e95b8e91499df2d83ecad3a77c3a3064dab3a","tarball_url":"https://registry.emisar.dev/v1/packs/firewall/0.1.15/888107ae1a1fe436c6e067cccf5e95b8e91499df2d83ecad3a77c3a3064dab3a/pack.tar.gz","requires":{"os":["linux"],"binaries":["iptables","nft","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","host_access":[{"actions":["fw.iptables_filter","fw.iptables_nat","fw.iptables_mangle","fw.nft_list_ruleset","fw.conntrack_count","fw.conntrack_list","fw.iptables_block_ip","fw.iptables_unblock_ip","fw.iptables_flush_chain","fw.nft_list_chain","fw.nft_port_rules"],"requirement":"Inspect and change the host network namespace with CAP_NET_ADMIN.","recipes":[{"name":"Grant CAP_NET_ADMIN to the Emisar service","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'AmbientCapabilities=CAP_NET_ADMIN' | sudo tee /etc/systemd/system/emisar.service.d/10-firewall-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["systemctl show emisar --property=AmbientCapabilities --value | grep -Fwi cap_net_admin"],"impact":"Every Emisar action on this runner inherits CAP_NET_ADMIN and can change routes, firewall rules, traffic control, and other network state in the host namespace."}]}],"verify":"fw.conntrack_count"},"actions":[{"id":"fw.conntrack_count","title":"conntrack count","summary":"Show active connection-tracking entry count + per-state breakdown.","description":"Show active connection-tracking entry count + per-state breakdown.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"Conntrack stats","args":{}}],"search_terms":["table full"],"command":{"binary":"/bin/sh","argv":["-c","set -e; echo 'Total:'; conntrack -C; echo; echo 'Per-state:'; conntrack -L | awk '{print $1,$4}' | sort | uniq -c | sort -rn | head -20"]}},{"id":"fw.conntrack_list","title":"conntrack -L (capped)","summary":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","description":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"First 1000 conntrack entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","conntrack -C >/dev/null 2>&1 || { echo \"conntrack unavailable (module not loaded or missing CAP_NET_ADMIN)\" >&2; exit 1; }\nconntrack -L | head -1000\n"]}},{"id":"fw.ip_rule_show","title":"ip rule show","summary":"Show policy routing rules — which routing table is used for which traffic.","description":"Show policy routing rules — which routing table is used for which traffic.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Policy rules","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["rule","show"]}},{"id":"fw.iptables_block_ip","title":"iptables -I INPUT -s <ip> -j DROP","summary":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","description":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","kind":"exec","risk":"high","side_effects":["One rule inserted at INPUT[1].","Traffic from that IP dropped immediately.","Rule is in-memory; lost on iptables restart unless saved."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Block a scanner","args":{"ip":"203.0.113.42"}}],"search_terms":["ban ip","blacklist","block attacker"],"command":{"binary":"iptables","argv":["-I","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.iptables_filter","title":"iptables -L -nv (filter table)","summary":"List all filter-table rules with packet + byte counters.","description":"List all filter-table rules with packet + byte counters.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Filter rules","args":{}}],"search_terms":["firewall rules","blocked traffic"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","filter"]}},{"id":"fw.iptables_flush_chain","title":"iptables -F <chain>","summary":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","description":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","kind":"exec","risk":"critical","side_effects":["All rules in the named chain removed.","If default policy is DROP, traffic immediately blocked.","Not persistent — undone by iptables service reload from saved rules."],"args":[{"name":"chain","type":"string","required":true,"description":"Chain name (INPUT, OUTPUT, FORWARD, or a custom chain).","validation":{"pattern":"^[A-Z][A-Z0-9_\\-]{0,31}$"}}],"examples":[{"title":"Flush a custom rate-limit chain","args":{"chain":"RATELIMIT"}}],"search_terms":[],"command":{"binary":"iptables","argv":["-F","{{ args.chain }}"]}},{"id":"fw.iptables_mangle","title":"iptables -L -nv (mangle table)","summary":"List all mangle-table rules — QoS marks, TTL tweaks.","description":"List all mangle-table rules — QoS marks, TTL tweaks.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Mangle rules","args":{}}],"search_terms":[],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","mangle"]}},{"id":"fw.iptables_nat","title":"iptables -L -nv (nat table)","summary":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","description":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"NAT rules","args":{}}],"search_terms":["port forwarding"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","nat"]}},{"id":"fw.iptables_unblock_ip","title":"iptables -D INPUT -s <ip> -j DROP","summary":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","description":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","kind":"exec","risk":"high","side_effects":["One matching DROP rule removed (or error if no match).","Traffic from that IP can flow again, subject to other rules."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Unblock after false-positive","args":{"ip":"10.0.5.12"}}],"search_terms":["unban"],"command":{"binary":"iptables","argv":["-D","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.nft_list_chain","title":"List one nftables chain as JSON","summary":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","description":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","kind":"exec","risk":"low","side_effects":["One read-only netfilter query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"family","type":"string","required":true,"description":"nftables address family.","validation":{"enum":["ip","ip6","inet","arp","bridge","netdev"]}},{"name":"table","type":"string","required":true,"description":"Exact nftables table name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}},{"name":"chain","type":"string","required":true,"description":"Exact nftables chain name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}}],"examples":[{"title":"Inspect the input chain","args":{"chain":"input","family":"inet","table":"filter"}}],"search_terms":[],"command":{"binary":"nft","argv":["-j","-n","-a","list","chain","{{ args.family }}","{{ args.table }}","{{ args.chain }}"]}},{"id":"fw.nft_list_ruleset","title":"nft list ruleset","summary":"Show the full nftables ruleset across all families.","description":"Show the full nftables ruleset across all families.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"All nft rules","args":{}}],"search_terms":["firewall rules"],"command":{"binary":"nft","argv":["list","ruleset"]}},{"id":"fw.nft_port_rules","title":"Project nftables rules for one port","summary":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","description":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","kind":"script","risk":"low","side_effects":["One read-only terse nftables ruleset query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP, UDP, SCTP, DCCP, or generic transport port to inspect.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Find direct and indirect rules involving PostgreSQL","args":{"port":5432}}],"search_terms":[]},{"id":"fw.tc_qdisc_show","title":"tc -s qdisc show","summary":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","description":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Active qdiscs","args":{}}],"search_terms":["bandwidth limit"],"command":{"binary":"tc","argv":["-s","qdisc","show"]}}],"previous_versions":[{"version":"0.1.13","content_hash":"sha256:5c836393c353bbaead823ca462fa0b214bc01d96c18ba49a86fd34d67dd8bea3","tarball_url":"https://registry.emisar.dev/v1/packs/firewall/0.1.13/5c836393c353bbaead823ca462fa0b214bc01d96c18ba49a86fd34d67dd8bea3/pack.tar.gz","actions":[{"id":"fw.conntrack_count","title":"conntrack count","summary":"Show active connection-tracking entry count + per-state breakdown.","description":"Show active connection-tracking entry count + per-state breakdown.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"Conntrack stats","args":{}}],"search_terms":["table full"],"command":{"binary":"/bin/sh","argv":["-c","set -e; echo 'Total:'; conntrack -C; echo; echo 'Per-state:'; conntrack -L | awk '{print $1,$4}' | sort | uniq -c | sort -rn | head -20"]}},{"id":"fw.conntrack_list","title":"conntrack -L (capped)","summary":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","description":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"First 1000 conntrack entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","conntrack -C >/dev/null 2>&1 || { echo \"conntrack unavailable (module not loaded or missing CAP_NET_ADMIN)\" >&2; exit 1; }\nconntrack -L | head -1000\n"]}},{"id":"fw.ip_rule_show","title":"ip rule show","summary":"Show policy routing rules — which routing table is used for which traffic.","description":"Show policy routing rules — which routing table is used for which traffic.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Policy rules","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["rule","show"]}},{"id":"fw.iptables_block_ip","title":"iptables -I INPUT -s <ip> -j DROP","summary":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","description":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","kind":"exec","risk":"high","side_effects":["One rule inserted at INPUT[1].","Traffic from that IP dropped immediately.","Rule is in-memory; lost on iptables restart unless saved."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Block a scanner","args":{"ip":"203.0.113.42"}}],"search_terms":["ban ip","blacklist","block attacker"],"command":{"binary":"iptables","argv":["-I","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.iptables_filter","title":"iptables -L -nv (filter table)","summary":"List all filter-table rules with packet + byte counters.","description":"List all filter-table rules with packet + byte counters.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Filter rules","args":{}}],"search_terms":["firewall rules","blocked traffic"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","filter"]}},{"id":"fw.iptables_flush_chain","title":"iptables -F <chain>","summary":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","description":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","kind":"exec","risk":"critical","side_effects":["All rules in the named chain removed.","If default policy is DROP, traffic immediately blocked.","Not persistent — undone by iptables service reload from saved rules."],"args":[{"name":"chain","type":"string","required":true,"description":"Chain name (INPUT, OUTPUT, FORWARD, or a custom chain).","validation":{"pattern":"^[A-Z][A-Z0-9_\\-]{0,31}$"}}],"examples":[{"title":"Flush a custom rate-limit chain","args":{"chain":"RATELIMIT"}}],"search_terms":[],"command":{"binary":"iptables","argv":["-F","{{ args.chain }}"]}},{"id":"fw.iptables_mangle","title":"iptables -L -nv (mangle table)","summary":"List all mangle-table rules — QoS marks, TTL tweaks.","description":"List all mangle-table rules — QoS marks, TTL tweaks.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Mangle rules","args":{}}],"search_terms":[],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","mangle"]}},{"id":"fw.iptables_nat","title":"iptables -L -nv (nat table)","summary":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","description":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"NAT rules","args":{}}],"search_terms":["port forwarding"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","nat"]}},{"id":"fw.iptables_unblock_ip","title":"iptables -D INPUT -s <ip> -j DROP","summary":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","description":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","kind":"exec","risk":"high","side_effects":["One matching DROP rule removed (or error if no match).","Traffic from that IP can flow again, subject to other rules."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Unblock after false-positive","args":{"ip":"10.0.5.12"}}],"search_terms":["unban"],"command":{"binary":"iptables","argv":["-D","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.nft_list_chain","title":"List one nftables chain as JSON","summary":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","description":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","kind":"exec","risk":"low","side_effects":["One read-only netfilter query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"family","type":"string","required":true,"description":"nftables address family.","validation":{"enum":["ip","ip6","inet","arp","bridge","netdev"]}},{"name":"table","type":"string","required":true,"description":"Exact nftables table name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}},{"name":"chain","type":"string","required":true,"description":"Exact nftables chain name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}}],"examples":[{"title":"Inspect the input chain","args":{"chain":"input","family":"inet","table":"filter"}}],"search_terms":[],"command":{"binary":"nft","argv":["-j","-n","-a","list","chain","{{ args.family }}","{{ args.table }}","{{ args.chain }}"]}},{"id":"fw.nft_list_ruleset","title":"nft list ruleset","summary":"Show the full nftables ruleset across all families.","description":"Show the full nftables ruleset across all families.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"All nft rules","args":{}}],"search_terms":["firewall rules"],"command":{"binary":"nft","argv":["list","ruleset"]}},{"id":"fw.nft_port_rules","title":"Project nftables rules for one port","summary":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","description":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","kind":"script","risk":"low","side_effects":["One read-only terse nftables ruleset query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP, UDP, SCTP, DCCP, or generic transport port to inspect.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Find direct and indirect rules involving PostgreSQL","args":{"port":5432}}],"search_terms":[]},{"id":"fw.tc_qdisc_show","title":"tc -s qdisc show","summary":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","description":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Active qdiscs","args":{}}],"search_terms":["bandwidth limit"],"command":{"binary":"tc","argv":["-s","qdisc","show"]}}]},{"version":"0.1.12","content_hash":"sha256:0c7b40d32bb0ac8e6e017773d49c840d75566e710678bcdb5e50a7170074d854","tarball_url":"https://registry.emisar.dev/v1/packs/firewall/0.1.12/0c7b40d32bb0ac8e6e017773d49c840d75566e710678bcdb5e50a7170074d854/pack.tar.gz","actions":[{"id":"fw.conntrack_count","title":"conntrack count","summary":"Show active connection-tracking entry count + per-state breakdown.","description":"Show active connection-tracking entry count + per-state breakdown.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"Conntrack stats","args":{}}],"search_terms":["table full"],"command":{"binary":"/bin/sh","argv":["-c","set -e; echo 'Total:'; conntrack -C; echo; echo 'Per-state:'; conntrack -L | awk '{print $1,$4}' | sort | uniq -c | sort -rn | head -20"]}},{"id":"fw.conntrack_list","title":"conntrack -L (capped)","summary":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","description":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"First 1000 conntrack entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","conntrack -C >/dev/null 2>&1 || { echo \"conntrack unavailable (module not loaded or missing CAP_NET_ADMIN)\" >&2; exit 1; }\nconntrack -L | head -1000\n"]}},{"id":"fw.ip_rule_show","title":"ip rule show","summary":"Show policy routing rules — which routing table is used for which traffic.","description":"Show policy routing rules — which routing table is used for which traffic.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Policy rules","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["rule","show"]}},{"id":"fw.iptables_block_ip","title":"iptables -I INPUT -s <ip> -j DROP","summary":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","description":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","kind":"exec","risk":"high","side_effects":["One rule inserted at INPUT[1].","Traffic from that IP dropped immediately.","Rule is in-memory; lost on iptables restart unless saved."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Block a scanner","args":{"ip":"203.0.113.42"}}],"search_terms":["ban ip","blacklist","block attacker"],"command":{"binary":"iptables","argv":["-I","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.iptables_filter","title":"iptables -L -nv (filter table)","summary":"List all filter-table rules with packet + byte counters.","description":"List all filter-table rules with packet + byte counters.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Filter rules","args":{}}],"search_terms":["firewall rules","blocked traffic"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","filter"]}},{"id":"fw.iptables_flush_chain","title":"iptables -F <chain>","summary":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","description":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","kind":"exec","risk":"critical","side_effects":["All rules in the named chain removed.","If default policy is DROP, traffic immediately blocked.","Not persistent — undone by iptables service reload from saved rules."],"args":[{"name":"chain","type":"string","required":true,"description":"Chain name (INPUT, OUTPUT, FORWARD, or a custom chain).","validation":{"pattern":"^[A-Z][A-Z0-9_\\-]{0,31}$"}}],"examples":[{"title":"Flush a custom rate-limit chain","args":{"chain":"RATELIMIT"}}],"search_terms":[],"command":{"binary":"iptables","argv":["-F","{{ args.chain }}"]}},{"id":"fw.iptables_mangle","title":"iptables -L -nv (mangle table)","summary":"List all mangle-table rules — QoS marks, TTL tweaks.","description":"List all mangle-table rules — QoS marks, TTL tweaks.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Mangle rules","args":{}}],"search_terms":[],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","mangle"]}},{"id":"fw.iptables_nat","title":"iptables -L -nv (nat table)","summary":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","description":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"NAT rules","args":{}}],"search_terms":["port forwarding"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","nat"]}},{"id":"fw.iptables_unblock_ip","title":"iptables -D INPUT -s <ip> -j DROP","summary":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","description":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","kind":"exec","risk":"high","side_effects":["One matching DROP rule removed (or error if no match).","Traffic from that IP can flow again, subject to other rules."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Unblock after false-positive","args":{"ip":"10.0.5.12"}}],"search_terms":["unban"],"command":{"binary":"iptables","argv":["-D","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.nft_list_chain","title":"List one nftables chain as JSON","summary":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","description":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","kind":"exec","risk":"low","side_effects":["One read-only netfilter query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"family","type":"string","required":true,"description":"nftables address family.","validation":{"enum":["ip","ip6","inet","arp","bridge","netdev"]}},{"name":"table","type":"string","required":true,"description":"Exact nftables table name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}},{"name":"chain","type":"string","required":true,"description":"Exact nftables chain name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}}],"examples":[{"title":"Inspect the input chain","args":{"chain":"input","family":"inet","table":"filter"}}],"search_terms":[],"command":{"binary":"nft","argv":["-j","-n","-a","list","chain","{{ args.family }}","{{ args.table }}","{{ args.chain }}"]}},{"id":"fw.nft_list_ruleset","title":"nft list ruleset","summary":"Show the full nftables ruleset across all families.","description":"Show the full nftables ruleset across all families.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"All nft rules","args":{}}],"search_terms":["firewall rules"],"command":{"binary":"nft","argv":["list","ruleset"]}},{"id":"fw.nft_port_rules","title":"Project nftables rules for one port","summary":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","description":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","kind":"script","risk":"low","side_effects":["One read-only terse nftables ruleset query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP, UDP, SCTP, DCCP, or generic transport port to inspect.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Find direct and indirect rules involving PostgreSQL","args":{"port":5432}}],"search_terms":[]},{"id":"fw.tc_qdisc_show","title":"tc -s qdisc show","summary":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","description":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Active qdiscs","args":{}}],"search_terms":["bandwidth limit"],"command":{"binary":"tc","argv":["-s","qdisc","show"]}}]},{"version":"0.1.11","content_hash":"sha256:bbf29caeed376680116b91ce5bc814850edf57f5549419e655111fd6304916ce","tarball_url":"https://registry.emisar.dev/v1/packs/firewall/0.1.11/bbf29caeed376680116b91ce5bc814850edf57f5549419e655111fd6304916ce/pack.tar.gz","actions":[{"id":"fw.conntrack_count","title":"conntrack count","summary":"Show active connection-tracking entry count + per-state breakdown.","description":"Show active connection-tracking entry count + per-state breakdown.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"Conntrack stats","args":{}}],"search_terms":["table full"],"command":{"binary":"/bin/sh","argv":["-c","set -e; echo 'Total:'; conntrack -C; echo; echo 'Per-state:'; conntrack -L | awk '{print $1,$4}' | sort | uniq -c | sort -rn | head -20"]}},{"id":"fw.conntrack_list","title":"conntrack -L (capped)","summary":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","description":"List the first 1000 connection-tracking entries. Use to see what's NAT'd right now.","kind":"exec","risk":"low","side_effects":["One conntrack query.","Read-only."],"args":[],"examples":[{"title":"First 1000 conntrack entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","conntrack -C >/dev/null 2>&1 || { echo \"conntrack unavailable (module not loaded or missing CAP_NET_ADMIN)\" >&2; exit 1; }\nconntrack -L | head -1000\n"]}},{"id":"fw.ip_rule_show","title":"ip rule show","summary":"Show policy routing rules — which routing table is used for which traffic.","description":"Show policy routing rules — which routing table is used for which traffic.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Policy rules","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["rule","show"]}},{"id":"fw.iptables_block_ip","title":"iptables -I INPUT -s <ip> -j DROP","summary":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","description":"Insert a DROP rule for one source IP at the top of the INPUT chain. Use during an active incident to immediately block a known-bad source. Rule is not persistent — survives only until iptables service reload or reboot. Combine with iptables-save to persist.","kind":"exec","risk":"high","side_effects":["One rule inserted at INPUT[1].","Traffic from that IP dropped immediately.","Rule is in-memory; lost on iptables restart unless saved."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Block a scanner","args":{"ip":"203.0.113.42"}}],"search_terms":["ban ip","blacklist","block attacker"],"command":{"binary":"iptables","argv":["-I","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.iptables_filter","title":"iptables -L -nv (filter table)","summary":"List all filter-table rules with packet + byte counters.","description":"List all filter-table rules with packet + byte counters.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Filter rules","args":{}}],"search_terms":["firewall rules","blocked traffic"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","filter"]}},{"id":"fw.iptables_flush_chain","title":"iptables -F <chain>","summary":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","description":"Flush all rules from a single chain. ALL rules in that chain are removed; default policy still applies. INPUT/FORWARD with a DROP default plus a flushed chain means ALL traffic is dropped — only use during planned firewall rebuilds with console access ready.","kind":"exec","risk":"critical","side_effects":["All rules in the named chain removed.","If default policy is DROP, traffic immediately blocked.","Not persistent — undone by iptables service reload from saved rules."],"args":[{"name":"chain","type":"string","required":true,"description":"Chain name (INPUT, OUTPUT, FORWARD, or a custom chain).","validation":{"pattern":"^[A-Z][A-Z0-9_\\-]{0,31}$"}}],"examples":[{"title":"Flush a custom rate-limit chain","args":{"chain":"RATELIMIT"}}],"search_terms":[],"command":{"binary":"iptables","argv":["-F","{{ args.chain }}"]}},{"id":"fw.iptables_mangle","title":"iptables -L -nv (mangle table)","summary":"List all mangle-table rules — QoS marks, TTL tweaks.","description":"List all mangle-table rules — QoS marks, TTL tweaks.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"Mangle rules","args":{}}],"search_terms":[],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","mangle"]}},{"id":"fw.iptables_nat","title":"iptables -L -nv (nat table)","summary":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","description":"List all nat-table rules — DNAT/SNAT/MASQUERADE.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"NAT rules","args":{}}],"search_terms":["port forwarding"],"command":{"binary":"iptables","argv":["-L","-nv","--line-numbers","-t","nat"]}},{"id":"fw.iptables_unblock_ip","title":"iptables -D INPUT -s <ip> -j DROP","summary":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","description":"Remove a previously-inserted DROP rule for one IP. Use to undo a manual block. Matches the rule by literal -s/-j signature; if the rule isn't found, iptables errors and nothing changes.","kind":"exec","risk":"high","side_effects":["One matching DROP rule removed (or error if no match).","Traffic from that IP can flow again, subject to other rules."],"args":[{"name":"ip","type":"string","required":true,"description":"Source IP address or CIDR.","validation":{"pattern":"^[0-9a-fA-F:.\\/]{1,43}$"}}],"examples":[{"title":"Unblock after false-positive","args":{"ip":"10.0.5.12"}}],"search_terms":["unban"],"command":{"binary":"iptables","argv":["-D","INPUT","-s","{{ args.ip }}","-j","DROP"]}},{"id":"fw.nft_list_chain","title":"List one nftables chain as JSON","summary":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","description":"Return native nftables JSON for one exact chain, including rule handles and numeric protocol and port values.","kind":"exec","risk":"low","side_effects":["One read-only netfilter query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"family","type":"string","required":true,"description":"nftables address family.","validation":{"enum":["ip","ip6","inet","arp","bridge","netdev"]}},{"name":"table","type":"string","required":true,"description":"Exact nftables table name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}},{"name":"chain","type":"string","required":true,"description":"Exact nftables chain name.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}$","max_length":64}}],"examples":[{"title":"Inspect the input chain","args":{"chain":"input","family":"inet","table":"filter"}}],"search_terms":[],"command":{"binary":"nft","argv":["-j","-n","-a","list","chain","{{ args.family }}","{{ args.table }}","{{ args.chain }}"]}},{"id":"fw.nft_list_ruleset","title":"nft list ruleset","summary":"Show the full nftables ruleset across all families.","description":"Show the full nftables ruleset across all families.","kind":"exec","risk":"low","side_effects":["One netfilter query.","Read-only."],"args":[],"examples":[{"title":"All nft rules","args":{}}],"search_terms":["firewall rules"],"command":{"binary":"nft","argv":["list","ruleset"]}},{"id":"fw.nft_port_rules","title":"Project nftables rules for one port","summary":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","description":"Project rules with direct source or destination port expressions for one numeric port. Rules that reference named sets, maps, or unsupported expressions are returned separately as unresolved. This is inspection evidence, not an effective allow or deny decision: chain order, jumps, policies, and other predicates still apply.","kind":"script","risk":"low","side_effects":["One read-only terse nftables ruleset query.","Requires root or CAP_NET_ADMIN on most hosts."],"args":[{"name":"port","type":"integer","required":true,"description":"TCP, UDP, SCTP, DCCP, or generic transport port to inspect.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Find direct and indirect rules involving PostgreSQL","args":{"port":5432}}],"search_terms":[]},{"id":"fw.tc_qdisc_show","title":"tc -s qdisc show","summary":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","description":"List active traffic-control disciplines per interface + their counters. Use to see traffic shaping in effect.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Active qdiscs","args":{}}],"search_terms":["bandwidth limit"],"command":{"binary":"tc","argv":["-s","qdisc","show"]}}]}]},{"id":"frr","name":"FRRouting (FRR)","version":"0.1.6","description":"Query the local FRRouting daemons via vtysh — BGP summary + neighbors, BFD peers, IP route summary, and interface state — plus one gated mutation: shut a BGP neighbor to drain a node from an anycast VIP. Reads are `show` commands; the drain is policy-gated (risk: high).","vendor":"emisar","homepage":"https://emisar.dev/packs/frr","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/frr","content_hash":"sha256:449a1cd5bd73a261a8a12c82651b13ae34f7c0ce50f6abba01cd65933aeccee8","tarball_url":"https://registry.emisar.dev/v1/packs/frr/0.1.6/449a1cd5bd73a261a8a12c82651b13ae34f7c0ce50f6abba01cd65933aeccee8/pack.tar.gz","requires":{"os":["linux"],"binaries":["vtysh"]},"detect":{"binaries":["vtysh"],"processes":["zebra"],"ports":[]},"setup":{"summary":"Queries the local FRR daemons through vtysh — no credentials needed. vtysh needs root or membership in the frrvty group to reach the daemon vty sockets.","notes":["The `show` actions are read-only; an unconfigured protocol (no BGP, no BFD) returns an empty / 'no process' result rather than failing. bgp_neighbor_shutdown is the one mutation — risk: high, policy-gated, and reversible (`no neighbor <peer> shutdown`)."],"host_access":[{"actions":["frr.bgp_summary","frr.bgp_neighbors","frr.bfd_peers","frr.route_summary","frr.interfaces","frr.bgp_neighbor_shutdown"],"requirement":"Reach FRR's VTY sockets. The operating-system boundary does not distinguish show from configuration commands.","recipes":[{"name":"Add the Emisar service user to frrvty","commands":["sudo usermod -aG frrvty emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx frrvty","sudo -u emisar vtysh -c 'show version' >/dev/null"],"impact":"Every process running as emisar can use VTYSH configuration commands and change FRR's full running configuration, not only the mutation exposed by this pack."}]}],"verify":"frr.bgp_summary"},"actions":[{"id":"frr.bfd_peers","title":"vtysh -c \"show bfd peers\"","summary":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","description":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BFD peer states","args":{}}],"search_terms":["fast failover","link failure detection"],"command":{"binary":"vtysh","argv":["-c","show bfd peers"]}},{"id":"frr.bgp_neighbor_shutdown","title":"vtysh -c \"router bgp <asn>\" -c \"neighbor <peer> shutdown\"","summary":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","description":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","kind":"exec","risk":"high","side_effects":["Shuts the BGP session to the named peer; this node withdraws every prefix it advertises to it (often just an anycast /32 — frr.bgp_summary PfxSnt shows the count).","For an anycast VIP, upstream ECMP drops this node within a BFD interval and traffic shifts to the remaining advertisers.","Running-config only — not written to startup-config, so an FRR restart or reboot re-advertises.","Reversible with `no neighbor <peer> shutdown` (re-advertise when the node is healthy again)."],"args":[{"name":"asn","type":"integer","required":true,"description":"Local BGP autonomous system number (the `router bgp <asn>` this neighbor lives under).","validation":{"min":1,"max":4294967295}},{"name":"peer","type":"string","required":true,"description":"Neighbor to shut — an IPv4/IPv6 address, peer-group, or interface name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,63}$"}}],"examples":[{"title":"Drain this node from the anycast VIP","args":{"asn":65010,"peer":"10.0.0.1"}}],"search_terms":["drain traffic","take node out of rotation","maintenance drain"],"command":{"binary":"vtysh","argv":["-c","configure terminal","-c","router bgp {{ args.asn }}","-c","neighbor {{ args.peer }} shutdown"]}},{"id":"frr.bgp_neighbors","title":"vtysh -c \"show bgp neighbors\"","summary":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","description":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP neighbor detail","args":{}}],"search_terms":["peer flapping","session resets"],"command":{"binary":"vtysh","argv":["-c","show bgp neighbors"]}},{"id":"frr.bgp_summary","title":"vtysh -c \"show bgp summary\"","summary":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","description":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP session summary","args":{}}],"search_terms":["bgp down","peering","bgp neighbor down"],"command":{"binary":"vtysh","argv":["-c","show bgp summary"]}},{"id":"frr.interfaces","title":"vtysh -c \"show interface brief\"","summary":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","description":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show interface brief"]}},{"id":"frr.route_summary","title":"vtysh -c \"show ip route summary\"","summary":"Show IP route table summary — route and FIB counts grouped by source protocol.","description":"Show IP route table summary — route and FIB counts grouped by source protocol.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Route counts by protocol","args":{}}],"search_terms":["routing table size"],"command":{"binary":"vtysh","argv":["-c","show ip route summary"]}}],"previous_versions":[{"version":"0.1.5","content_hash":"sha256:bc9631e5a4da1d98b28d5f3051c541c4db9c4f2fbcfc73aa6976ab91fcad2a21","tarball_url":"https://registry.emisar.dev/v1/packs/frr/0.1.5/bc9631e5a4da1d98b28d5f3051c541c4db9c4f2fbcfc73aa6976ab91fcad2a21/pack.tar.gz","actions":[{"id":"frr.bfd_peers","title":"vtysh -c \"show bfd peers\"","summary":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","description":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BFD peer states","args":{}}],"search_terms":["fast failover","link failure detection"],"command":{"binary":"vtysh","argv":["-c","show bfd peers"]}},{"id":"frr.bgp_neighbor_shutdown","title":"vtysh -c \"router bgp <asn>\" -c \"neighbor <peer> shutdown\"","summary":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","description":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","kind":"exec","risk":"high","side_effects":["Shuts the BGP session to the named peer; this node withdraws every prefix it advertises to it (often just an anycast /32 — frr.bgp_summary PfxSnt shows the count).","For an anycast VIP, upstream ECMP drops this node within a BFD interval and traffic shifts to the remaining advertisers.","Running-config only — not written to startup-config, so an FRR restart or reboot re-advertises.","Reversible with `no neighbor <peer> shutdown` (re-advertise when the node is healthy again)."],"args":[{"name":"asn","type":"integer","required":true,"description":"Local BGP autonomous system number (the `router bgp <asn>` this neighbor lives under).","validation":{"min":1,"max":4294967295}},{"name":"peer","type":"string","required":true,"description":"Neighbor to shut — an IPv4/IPv6 address, peer-group, or interface name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,63}$"}}],"examples":[{"title":"Drain this node from the anycast VIP","args":{"asn":65010,"peer":"10.0.0.1"}}],"search_terms":["drain traffic","take node out of rotation","maintenance drain"],"command":{"binary":"vtysh","argv":["-c","configure terminal","-c","router bgp {{ args.asn }}","-c","neighbor {{ args.peer }} shutdown"]}},{"id":"frr.bgp_neighbors","title":"vtysh -c \"show bgp neighbors\"","summary":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","description":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP neighbor detail","args":{}}],"search_terms":["peer flapping","session resets"],"command":{"binary":"vtysh","argv":["-c","show bgp neighbors"]}},{"id":"frr.bgp_summary","title":"vtysh -c \"show bgp summary\"","summary":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","description":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP session summary","args":{}}],"search_terms":["bgp down","peering","bgp neighbor down"],"command":{"binary":"vtysh","argv":["-c","show bgp summary"]}},{"id":"frr.interfaces","title":"vtysh -c \"show interface brief\"","summary":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","description":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show interface brief"]}},{"id":"frr.route_summary","title":"vtysh -c \"show ip route summary\"","summary":"Show IP route table summary — route and FIB counts grouped by source protocol.","description":"Show IP route table summary — route and FIB counts grouped by source protocol.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Route counts by protocol","args":{}}],"search_terms":["routing table size"],"command":{"binary":"vtysh","argv":["-c","show ip route summary"]}}]},{"version":"0.1.4","content_hash":"sha256:e918df8551e73607dec0f6304c0166da4dd8b307396a9f4acea70cb0916763c6","tarball_url":"https://registry.emisar.dev/v1/packs/frr/0.1.4/e918df8551e73607dec0f6304c0166da4dd8b307396a9f4acea70cb0916763c6/pack.tar.gz","actions":[{"id":"frr.bfd_peers","title":"vtysh -c \"show bfd peers\"","summary":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","description":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BFD peer states","args":{}}],"search_terms":["fast failover","link failure detection"],"command":{"binary":"vtysh","argv":["-c","show bfd peers"]}},{"id":"frr.bgp_neighbor_shutdown","title":"vtysh -c \"router bgp <asn>\" -c \"neighbor <peer> shutdown\"","summary":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","description":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","kind":"exec","risk":"high","side_effects":["Shuts the BGP session to the named peer; this node withdraws every prefix it advertises to it (often just an anycast /32 — frr.bgp_summary PfxSnt shows the count).","For an anycast VIP, upstream ECMP drops this node within a BFD interval and traffic shifts to the remaining advertisers.","Running-config only — not written to startup-config, so an FRR restart or reboot re-advertises.","Reversible with `no neighbor <peer> shutdown` (re-advertise when the node is healthy again)."],"args":[{"name":"asn","type":"integer","required":true,"description":"Local BGP autonomous system number (the `router bgp <asn>` this neighbor lives under).","validation":{"min":1,"max":4294967295}},{"name":"peer","type":"string","required":true,"description":"Neighbor to shut — an IPv4/IPv6 address, peer-group, or interface name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,63}$"}}],"examples":[{"title":"Drain this node from the anycast VIP","args":{"asn":65010,"peer":"10.0.0.1"}}],"search_terms":["drain traffic","take node out of rotation","maintenance drain"],"command":{"binary":"vtysh","argv":["-c","configure terminal","-c","router bgp {{ args.asn }}","-c","neighbor {{ args.peer }} shutdown"]}},{"id":"frr.bgp_neighbors","title":"vtysh -c \"show bgp neighbors\"","summary":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","description":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP neighbor detail","args":{}}],"search_terms":["peer flapping","session resets"],"command":{"binary":"vtysh","argv":["-c","show bgp neighbors"]}},{"id":"frr.bgp_summary","title":"vtysh -c \"show bgp summary\"","summary":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","description":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP session summary","args":{}}],"search_terms":["bgp down","peering","bgp neighbor down"],"command":{"binary":"vtysh","argv":["-c","show bgp summary"]}},{"id":"frr.interfaces","title":"vtysh -c \"show interface brief\"","summary":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","description":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show interface brief"]}},{"id":"frr.route_summary","title":"vtysh -c \"show ip route summary\"","summary":"Show IP route table summary — route and FIB counts grouped by source protocol.","description":"Show IP route table summary — route and FIB counts grouped by source protocol.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Route counts by protocol","args":{}}],"search_terms":["routing table size"],"command":{"binary":"vtysh","argv":["-c","show ip route summary"]}}]},{"version":"0.1.3","content_hash":"sha256:10d44915dd07d4a57de04f06d5a780c98dd567260912c2a9359184a0084f3ea3","tarball_url":"https://registry.emisar.dev/v1/packs/frr/0.1.3/10d44915dd07d4a57de04f06d5a780c98dd567260912c2a9359184a0084f3ea3/pack.tar.gz","actions":[{"id":"frr.bfd_peers","title":"vtysh -c \"show bfd peers\"","summary":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","description":"List BFD peer sessions — local/remote state (Up/Down), last diagnostic, and timers.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BFD peer states","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show bfd peers"]}},{"id":"frr.bgp_neighbor_shutdown","title":"vtysh -c \"router bgp <asn>\" -c \"neighbor <peer> shutdown\"","summary":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","description":"Administratively shut a BGP neighbor session via vtysh, withdrawing every prefix this node advertises to that peer — the governed way to drain a node from an anycast VIP so the upstream ECMP routes around it within a BFD interval. Reversible: re-advertise with `no neighbor <peer> shutdown` once the node is healthy. The change is to the running config only (not persisted), so a daemon restart re-advertises. Pair with frr.bgp_summary to confirm PfxSnt drops to 0 after the drain.","kind":"exec","risk":"high","side_effects":["Shuts the BGP session to the named peer; this node withdraws every prefix it advertises to it (often just an anycast /32 — frr.bgp_summary PfxSnt shows the count).","For an anycast VIP, upstream ECMP drops this node within a BFD interval and traffic shifts to the remaining advertisers.","Running-config only — not written to startup-config, so an FRR restart or reboot re-advertises.","Reversible with `no neighbor <peer> shutdown` (re-advertise when the node is healthy again)."],"args":[{"name":"asn","type":"integer","required":true,"description":"Local BGP autonomous system number (the `router bgp <asn>` this neighbor lives under).","validation":{"min":1,"max":4294967295}},{"name":"peer","type":"string","required":true,"description":"Neighbor to shut — an IPv4/IPv6 address, peer-group, or interface name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._:\\-]{0,63}$"}}],"examples":[{"title":"Drain this node from the anycast VIP","args":{"asn":65010,"peer":"10.0.0.1"}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","configure terminal","-c","router bgp {{ args.asn }}","-c","neighbor {{ args.peer }} shutdown"]}},{"id":"frr.bgp_neighbors","title":"vtysh -c \"show bgp neighbors\"","summary":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","description":"Show detailed BGP neighbor state — capabilities, timers, and message + prefix counters per peer.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP neighbor detail","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show bgp neighbors"]}},{"id":"frr.bgp_summary","title":"vtysh -c \"show bgp summary\"","summary":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","description":"Show BGP neighbor summary — per-peer state/uptime and prefix counts (PfxRcd / PfxSnt). The quick \"are my BGP sessions established and exchanging routes?\" check.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"BGP session summary","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show bgp summary"]}},{"id":"frr.interfaces","title":"vtysh -c \"show interface brief\"","summary":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","description":"Show interface brief — admin/protocol status, addresses, and VRF per interface as FRR sees them.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show interface brief"]}},{"id":"frr.route_summary","title":"vtysh -c \"show ip route summary\"","summary":"Show IP route table summary — route and FIB counts grouped by source protocol.","description":"Show IP route table summary — route and FIB counts grouped by source protocol.","kind":"exec","risk":"low","side_effects":["One vtysh show command.","Read-only."],"args":[],"examples":[{"title":"Route counts by protocol","args":{}}],"search_terms":[],"command":{"binary":"vtysh","argv":["-c","show ip route summary"]}}]}]},{"id":"fs-search","name":"Filesystem search and inspection","version":"0.1.15","description":"Generic filesystem operations an LLM-driven runner needs constantly: bounded find, recursive grep, file head/tail/hash, du, ls -la, stat. All read-only. Paths are validated against simple patterns; the runner's symlink-containment + audit redaction layers still apply on top.","vendor":"emisar","homepage":"https://emisar.dev/packs/fs-search","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/fs-search","content_hash":"sha256:97064ba1c472ae9b4a35abb2e5a3d4c8dadda78cff3a4d7106077c3c2ef18052","tarball_url":"https://registry.emisar.dev/v1/packs/fs-search/0.1.15/97064ba1c472ae9b4a35abb2e5a3d4c8dadda78cff3a4d7106077c3c2ef18052/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Reads the local filesystem on the runner host (find/grep/du/stat and friends) — no credentials needed; paths and patterns are passed as arguments.","notes":["The runner refuses any path inside its own configuration and state directories (`/etc/emisar` and `/var/lib/emisar` by default, or wherever --etc-dir/--data-dir put them) for every action, whatever a pack declares. Those hold the enrollment key, the pack credentials you exported, and this runner's bearer token.","The content-returning reads — `fs.head_file`, `fs.tail_file`, `fs.grep_file`, `fs.grep_recursive` — stay low risk for ordinary diagnostics but refuse `/dev`, `/proc/kcore`, and raw per-process `environ`, `mem`, and `fd` endpoints after canonical path validation. An `fd` link that resolves to an ordinary file receives the same final-target policy as a direct path. Useful `/proc` and `/sys` diagnostics such as memory, pressure, process status, and limits remain available.","A fleet that wants a human in the loop for every other file adds a policy override (`action: fs.*_file` or `action: fs.grep_*`, `decision: require_approval`) instead of changing the tier for everyone."],"host_access":[{"actions":["fs.find_by_name","fs.find_recent_modified","fs.find_world_writable","fs.find_setuid","fs.find_large_files","fs.du_top","fs.ls_long","fs.stat_path","fs.sha256_file","fs.head_file","fs.tail_file","fs.grep_file","fs.grep_recursive","fs.count_lines","fs.file_type"],"requirement":"Read root-owned or otherwise restricted target paths when those paths are intentionally in scope.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-fs-search-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root and can read nearly every host path allowed by the runner's hard path policy, including credentials and private data."}]}],"verify":"fs.stat_path"},"actions":[{"id":"fs.count_lines","title":"wc -l <file>","summary":"Count lines in one file.","description":"Count lines in one file.","kind":"exec","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"Line count of syslog","args":{"path":"/var/log/syslog"}}],"search_terms":[],"command":{"binary":"wc","argv":["-l","{{ args.path }}"]}},{"id":"fs.du_top","title":"du -d1 — top N entries","summary":"Show the 20 largest entries directly under one path, largest first — files and directories, hidden ones included. Use to find where the space went.","description":"Show the 20 largest entries directly under one path, largest first — files and directories, hidden ones included. Use to find where the space went.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"Where's the space in /var?","args":{"path":"/var"}}],"search_terms":["where did the space go","disk filling up","biggest directories"],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\ndu -ah --max-depth=1 --exclude=.ssh --exclude=ssh --exclude=private --exclude=sudoers.d \"$1\" 2>/dev/null | awk -F'\\t' -v root=\"$1\" '$2 != root' | sort -rh | head -20\n","emisar","{{ args.path }}"]}},{"id":"fs.file_type","title":"file <path>","summary":"Show the libmagic-detected type of one file (e.g. \"ELF 64-bit executable\", \"ASCII text\").","description":"Show the libmagic-detected type of one file (e.g. \"ELF 64-bit executable\", \"ASCII text\").","kind":"exec","risk":"low","side_effects":["One read of the first few KB of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"What is this binary?","args":{"path":"/usr/bin/sshd"}}],"search_terms":[],"command":{"binary":"file","argv":["{{ args.path }}"]}},{"id":"fs.find_by_name","title":"find -name <glob> under <path>","summary":"Find files matching one shell glob under one path. Capped at 1000 results.","description":"Find files matching one shell glob under one path. Capped at 1000 results.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"glob","type":"string","required":true,"description":"Shell glob (e.g. '*.log').","validation":{"pattern":"^[a-zA-Z0-9_.*?[\\]\\-]{1,64}$"}},{"name":"max_depth","type":"integer","required":false,"default":6,"description":"Max directory depth.","validation":{"min":1,"max":20}}],"examples":[{"title":"Find .conf under /etc","args":{"glob":"*.conf","path":"/etc"}}],"search_terms":["locate"],"command":{"binary":"find","argv":["{{ args.path }}","-maxdepth","{{ args.max_depth }}","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-name","{{ args.glob }}","-print"]}},{"id":"fs.find_large_files","title":"Files larger than N MB","summary":"Find the top files by size under one path. Use to find disk-pressure culprits.","description":"Find the top files by size under one path. Use to find disk-pressure culprits.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"min_mb","type":"integer","required":false,"default":100,"description":"Minimum size in MB.","validation":{"min":1,"max":1000000}}],"examples":[{"title":"Files >500MB under /var","args":{"min_mb":500,"path":"/var"}}],"search_terms":["large files","big files","disk filling up","where did the space go"],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\nfind \"$1\" -xdev \\( -path /etc/ssh -o -path /etc/ssl/private -o -path /root/.ssh -o -path /etc/sudoers.d \\) -prune -o -type f -size +{{ args.min_mb }}M -printf '%s %p\\n' 2>/dev/null | sort -rn | head -50\n","emisar","{{ args.path }}"]}},{"id":"fs.find_recent_modified","title":"Files modified in last N minutes","summary":"Find files under one path modified within the last N minutes. Useful for \"what just changed?\".","description":"Find files under one path modified within the last N minutes. Useful for \"what just changed?\".","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"minutes","type":"integer","required":false,"default":60,"description":"Mtime window in minutes.","validation":{"min":1,"max":10080}},{"name":"max_depth","type":"integer","required":false,"default":6,"description":"Max directory depth.","validation":{"min":1,"max":20}}],"examples":[{"title":"Recently touched config files","args":{"minutes":1440,"path":"/etc"}}],"search_terms":[],"command":{"binary":"find","argv":["{{ args.path }}","-maxdepth","{{ args.max_depth }}","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-type","f","-mmin","-{{ args.minutes }}","-printf","%T@ %p\\n"]}},{"id":"fs.find_setuid","title":"setuid + setgid files","summary":"Find files with setuid or setgid bits. Audit for privilege escalation surface.","description":"Find files with setuid or setgid bits. Audit for privilege escalation surface.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":false,"default":"/","description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"setuid/setgid binaries","args":{}}],"search_terms":["suid","sgid"],"command":{"binary":"find","argv":["{{ args.path }}","-xdev","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-type","f","(","-perm","-4000","-o","-perm","-2000",")","-print"]}},{"id":"fs.find_world_writable","title":"World-writable files","summary":"Find files with the \"world-writable\" bit set under one path. Security audit.","description":"Find files with the \"world-writable\" bit set under one path. Security audit.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"World-writable under /opt","args":{"path":"/opt"}}],"search_terms":["insecure permissions"],"command":{"binary":"find","argv":["{{ args.path }}","-xdev","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-type","f","-perm","-0002","-print"]}},{"id":"fs.grep_file","title":"grep <pattern> <file>","summary":"Show matching lines in one file. Pattern is treated as POSIX ERE.","description":"Show matching lines in one file. Pattern is treated as POSIX ERE.","kind":"script","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"pattern","type":"string","required":true,"description":"Regex.","validation":{"pattern":"^[^'\"`$;|&<>]{1,256}$"}},{"name":"case_insensitive","type":"boolean","required":false,"default":false,"description":"-i mode."}],"examples":[{"title":"grep ERROR in syslog","args":{"path":"/var/log/syslog","pattern":"ERROR"}}],"search_terms":[]},{"id":"fs.grep_recursive","title":"grep -rE <pattern> <path>","summary":"Search recursively under one path. Bounded to 500 matches.","description":"Search recursively under one path. Bounded to 500 matches.","kind":"script","risk":"low","side_effects":["Recursive file-system traversal + read of matched files.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"pattern","type":"string","required":true,"description":"Regex.","validation":{"pattern":"^[^'\"`$;|&<>]{1,256}$"}}],"examples":[{"title":"Find calls to deprecated API","args":{"path":"/opt/app/src","pattern":"deprecated_call"}}],"search_terms":[]},{"id":"fs.head_file","title":"head -n <N> <file>","summary":"Show the first N lines of one file.","description":"Show the first N lines of one file.","kind":"script","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"lines","type":"integer","required":false,"default":100,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"First 100 lines","args":{"path":"/var/log/syslog"}}],"search_terms":[]},{"id":"fs.ls_long","title":"ls -la <path>","summary":"List directory contents in long format.","description":"List directory contents in long format.","kind":"exec","risk":"low","side_effects":["One directory read.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Directory.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"ls /etc","args":{"path":"/etc"}}],"search_terms":[],"command":{"binary":"ls","argv":["-la","--time-style=long-iso","{{ args.path }}"]}},{"id":"fs.sha256_file","title":"sha256sum <file>","summary":"Show the SHA-256 of one file. Use to confirm a binary matches a known-good hash.","description":"Show the SHA-256 of one file. Use to confirm a binary matches a known-good hash.","kind":"exec","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"Hash a binary","args":{"path":"/usr/bin/sshd"}}],"search_terms":["checksum","integrity"],"command":{"binary":"sha256sum","argv":["{{ args.path }}"]}},{"id":"fs.stat_path","title":"stat <path>","summary":"Show inode + timestamps + permissions for one path.","description":"Show inode + timestamps + permissions for one path.","kind":"exec","risk":"low","side_effects":["One stat() call.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}}],"examples":[{"title":"stat /etc/passwd","args":{"path":"/etc/passwd"}}],"search_terms":[],"command":{"binary":"stat","argv":["{{ args.path }}"]}},{"id":"fs.tail_file","title":"tail -n <N> <file>","summary":"Show the last N lines of one file.","description":"Show the last N lines of one file.","kind":"script","risk":"medium","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar","/var/log/emisar"]}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines","args":{"path":"/var/log/syslog"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.12","content_hash":"sha256:b505bdbf2e342aa270a77c6137f316f26c90285e2ea7b2440df750e8b3aa2c1b","tarball_url":"https://registry.emisar.dev/v1/packs/fs-search/0.1.12/b505bdbf2e342aa270a77c6137f316f26c90285e2ea7b2440df750e8b3aa2c1b/pack.tar.gz","actions":[{"id":"fs.count_lines","title":"wc -l <file>","summary":"Count lines in one file.","description":"Count lines in one file.","kind":"exec","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"Line count of syslog","args":{"path":"/var/log/syslog"}}],"search_terms":[],"command":{"binary":"wc","argv":["-l","{{ args.path }}"]}},{"id":"fs.du_top","title":"du -d1 — top N entries","summary":"Show the 20 largest entries directly under one path, largest first — files and directories, hidden ones included. Use to find where the space went.","description":"Show the 20 largest entries directly under one path, largest first — files and directories, hidden ones included. Use to find where the space went.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"Where's the space in /var?","args":{"path":"/var"}}],"search_terms":["where did the space go","disk filling up","biggest directories"],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\ndu -ah --max-depth=1 --exclude=.ssh --exclude=ssh --exclude=private --exclude=sudoers.d \"$1\" 2>/dev/null | awk -F'\\t' -v root=\"$1\" '$2 != root' | sort -rh | head -20\n","emisar","{{ args.path }}"]}},{"id":"fs.file_type","title":"file <path>","summary":"Show the libmagic-detected type of one file (e.g. \"ELF 64-bit executable\", \"ASCII text\").","description":"Show the libmagic-detected type of one file (e.g. \"ELF 64-bit executable\", \"ASCII text\").","kind":"exec","risk":"low","side_effects":["One read of the first few KB of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"What is this binary?","args":{"path":"/usr/bin/sshd"}}],"search_terms":[],"command":{"binary":"file","argv":["{{ args.path }}"]}},{"id":"fs.find_by_name","title":"find -name <glob> under <path>","summary":"Find files matching one shell glob under one path. Capped at 1000 results.","description":"Find files matching one shell glob under one path. Capped at 1000 results.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"glob","type":"string","required":true,"description":"Shell glob (e.g. '*.log').","validation":{"pattern":"^[a-zA-Z0-9_.*?[\\]\\-]{1,64}$"}},{"name":"max_depth","type":"integer","required":false,"default":6,"description":"Max directory depth.","validation":{"min":1,"max":20}}],"examples":[{"title":"Find .conf under /etc","args":{"glob":"*.conf","path":"/etc"}}],"search_terms":["locate"],"command":{"binary":"find","argv":["{{ args.path }}","-maxdepth","{{ args.max_depth }}","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-name","{{ args.glob }}","-print"]}},{"id":"fs.find_large_files","title":"Files larger than N MB","summary":"Find the top files by size under one path. Use to find disk-pressure culprits.","description":"Find the top files by size under one path. Use to find disk-pressure culprits.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"min_mb","type":"integer","required":false,"default":100,"description":"Minimum size in MB.","validation":{"min":1,"max":1000000}}],"examples":[{"title":"Files >500MB under /var","args":{"min_mb":500,"path":"/var"}}],"search_terms":["large files","big files","disk filling up","where did the space go"],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\nfind \"$1\" -xdev \\( -path /etc/ssh -o -path /etc/ssl/private -o -path /root/.ssh -o -path /etc/sudoers.d \\) -prune -o -type f -size +{{ args.min_mb }}M -printf '%s %p\\n' 2>/dev/null | sort -rn | head -50\n","emisar","{{ args.path }}"]}},{"id":"fs.find_recent_modified","title":"Files modified in last N minutes","summary":"Find files under one path modified within the last N minutes. Useful for \"what just changed?\".","description":"Find files under one path modified within the last N minutes. Useful for \"what just changed?\".","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"minutes","type":"integer","required":false,"default":60,"description":"Mtime window in minutes.","validation":{"min":1,"max":10080}},{"name":"max_depth","type":"integer","required":false,"default":6,"description":"Max directory depth.","validation":{"min":1,"max":20}}],"examples":[{"title":"Recently touched config files","args":{"minutes":1440,"path":"/etc"}}],"search_terms":[],"command":{"binary":"find","argv":["{{ args.path }}","-maxdepth","{{ args.max_depth }}","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-type","f","-mmin","-{{ args.minutes }}","-printf","%T@ %p\\n"]}},{"id":"fs.find_setuid","title":"setuid + setgid files","summary":"Find files with setuid or setgid bits. Audit for privilege escalation surface.","description":"Find files with setuid or setgid bits. Audit for privilege escalation surface.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":false,"default":"/","description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"setuid/setgid binaries","args":{}}],"search_terms":["suid","sgid"],"command":{"binary":"find","argv":["{{ args.path }}","-xdev","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-type","f","(","-perm","-4000","-o","-perm","-2000",")","-print"]}},{"id":"fs.find_world_writable","title":"World-writable files","summary":"Find files with the \"world-writable\" bit set under one path. Security audit.","description":"Find files with the \"world-writable\" bit set under one path. Security audit.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"World-writable under /opt","args":{"path":"/opt"}}],"search_terms":["insecure permissions"],"command":{"binary":"find","argv":["{{ args.path }}","-xdev","(","-path","/etc/ssh","-o","-path","/etc/ssl/private","-o","-path","/root/.ssh","-o","-path","/etc/sudoers.d",")","-prune","-o","-type","f","-perm","-0002","-print"]}},{"id":"fs.grep_file","title":"grep <pattern> <file>","summary":"Show matching lines in one file. Pattern is treated as POSIX ERE.","description":"Show matching lines in one file. Pattern is treated as POSIX ERE.","kind":"script","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"pattern","type":"string","required":true,"description":"Regex.","validation":{"pattern":"^[^'\"`$;|&<>]{1,256}$"}},{"name":"case_insensitive","type":"boolean","required":false,"default":false,"description":"-i mode."}],"examples":[{"title":"grep ERROR in syslog","args":{"path":"/var/log/syslog","pattern":"ERROR"}}],"search_terms":[]},{"id":"fs.grep_recursive","title":"grep -rE <pattern> <path>","summary":"Search recursively under one path. Bounded to 500 matches.","description":"Search recursively under one path. Bounded to 500 matches.","kind":"script","risk":"low","side_effects":["Recursive file-system traversal + read of matched files.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"pattern","type":"string","required":true,"description":"Regex.","validation":{"pattern":"^[^'\"`$;|&<>]{1,256}$"}}],"examples":[{"title":"Find calls to deprecated API","args":{"path":"/opt/app/src","pattern":"deprecated_call"}}],"search_terms":[]},{"id":"fs.head_file","title":"head -n <N> <file>","summary":"Show the first N lines of one file.","description":"Show the first N lines of one file.","kind":"script","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"lines","type":"integer","required":false,"default":100,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"First 100 lines","args":{"path":"/var/log/syslog"}}],"search_terms":[]},{"id":"fs.ls_long","title":"ls -la <path>","summary":"List directory contents in long format.","description":"List directory contents in long format.","kind":"exec","risk":"low","side_effects":["One directory read.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Directory.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"ls /etc","args":{"path":"/etc"}}],"search_terms":[],"command":{"binary":"ls","argv":["-la","--time-style=long-iso","{{ args.path }}"]}},{"id":"fs.sha256_file","title":"sha256sum <file>","summary":"Show the SHA-256 of one file. Use to confirm a binary matches a known-good hash.","description":"Show the SHA-256 of one file. Use to confirm a binary matches a known-good hash.","kind":"exec","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"Hash a binary","args":{"path":"/usr/bin/sshd"}}],"search_terms":["checksum","integrity"],"command":{"binary":"sha256sum","argv":["{{ args.path }}"]}},{"id":"fs.stat_path","title":"stat <path>","summary":"Show inode + timestamps + permissions for one path.","description":"Show inode + timestamps + permissions for one path.","kind":"exec","risk":"low","side_effects":["One stat() call.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"Path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}}],"examples":[{"title":"stat /etc/passwd","args":{"path":"/etc/passwd"}}],"search_terms":[],"command":{"binary":"stat","argv":["{{ args.path }}"]}},{"id":"fs.tail_file","title":"tail -n <N> <file>","summary":"Show the last N lines of one file.","description":"Show the last N lines of one file.","kind":"script","risk":"low","side_effects":["One read of the file.","Read-only."],"args":[{"name":"path","type":"path","required":true,"description":"File path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-","/etc/sudoers","/proc/kcore"],"denied_prefixes":["/etc/ssl/private","/root/.ssh","/etc/ssh","/etc/sudoers.d","/etc/emisar","/var/lib/emisar"]}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 lines","args":{"path":"/var/log/syslog"}}],"search_terms":[]}]}],"retired_below":"0.1.12"},{"id":"gcp-billing","name":"Google Cloud billing and cost analytics","version":"0.2.2","description":"Read-only Google Cloud spend analytics — cost by service, project, and SKU, a daily trend, and export freshness — read from the Cloud Billing export in BigQuery, alongside billing account, linked project, and budget reads from the Cloud Billing API. Google Cloud publishes no cost-report API, so the cost actions read the billing export rather than a reporting endpoint.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-billing","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-billing","content_hash":"sha256:42a2143cd10352bb08390ae3c6b05ad33d297255574aedd7cfa6f111c8368a90","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-billing/0.2.2/42a2143cd10352bb08390ae3c6b05ad33d297255574aedd7cfa6f111c8368a90/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","curl","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Uses gcloud authentication on the runner host. The cost actions obtain a short-lived access token from gcloud and post an authored query to the fixed bigquery.googleapis.com endpoint, keeping the token out of argv and output.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional path to a credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-billing-reader.json"}],"notes":["Any credential/config env you set must be allowlisted in the runner's `execution.inherit_env`; attached service accounts and workload identity need no credential env.","The cost actions read whichever billing export the account turned on — the standard gcp_billing_export_v1_<BILLING_ACCOUNT_ID> table, or the detailed gcp_billing_export_resource_v1_<BILLING_ACCOUNT_ID> one — and name the table they read. Turn on Billing export to BigQuery first: it is not retroactive and takes up to a day to populate, so a fresh export answers recent windows only.","A detailed export splits the same charges into resource-level rows, so the same window scans more of it and a wide one may need a higher max_scan_gb.","The account, project, and budget reads need roles/billing.viewer bound on the billing account itself; a project-level binding does not reach it, and gcloud then reports that the caller does not have permission to access the billing account.","The cost queries additionally need roles/bigquery.jobUser on the query project and roles/bigquery.dataViewer on the export dataset, which also carries the table read that resolves the export.","Budget reads need billingbudgets.googleapis.com enabled on the quota project.","BigQuery bills every cost query by bytes scanned, so each cost action sends maximumBytesBilled from its max_scan_gb argument: an over-broad window fails outright instead of billing an unbounded scan.","Cost rows settle for several days after usage, and credits post on their own schedule, so a recent window is an estimate rather than the invoice.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed."],"verify":"gcp.billing_accounts"},"actions":[{"id":"gcp.billing_accounts","title":"gcloud billing accounts list","summary":"List Cloud Billing accounts the runner's credentials can see, with currency, open state, and parent organization.","description":"List Cloud Billing accounts the runner's credentials can see, with currency, open state, and parent organization.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing API pagination.","Returned accounts are capped by limit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum billing accounts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Visible billing accounts","args":{"limit":100}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","accounts","list","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.billing_budgets","title":"gcloud billing budgets list","summary":"List budgets on one Cloud Billing account, with their amounts, threshold rules, and the projects or services each one filters.","description":"List budgets on one Cloud Billing account, with their amounts, threshold rules, and the projects or services each one filters.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing Budget API pagination.","Returned budgets are capped by limit.","A budget states its threshold, not current spend; the cost actions report spend."],"args":[{"name":"billing_account","type":"string","required":true,"description":"Billing account ID, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum budgets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Budgets and thresholds on one account","args":{"billing_account":"01B678-5ED3E1-AD1F9F","limit":100}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","budgets","list","--billing-account={{ args.billing_account }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.billing_projects","title":"gcloud billing projects list","summary":"List projects billed to one Cloud Billing account, with each project's billing-enabled state.","description":"List projects billed to one Cloud Billing account, with each project's billing-enabled state.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing API pagination.","Returned projects are capped by limit."],"args":[{"name":"billing_account","type":"string","required":true,"description":"Billing account ID, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum projects to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Projects on one billing account","args":{"billing_account":"01B678-5ED3E1-AD1F9F","limit":200}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","projects","list","--billing-account={{ args.billing_account }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.cost_by_project","title":"Show Google Cloud cost by project","summary":"Show gross cost, credits, and net cost per project over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend. Charges that carry no project, such as support, group as (unattributed).","description":"Show gross cost, credits, and net cost per project over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend. Charges that carry no project, such as support, group as (unattributed).","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum projects to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Last 30 days by project","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"limit":50,"project":"example-prod"}},{"title":"Compute Engine spend split by project","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"project":"example-prod","service":"Compute Engine"}}],"search_terms":[]},{"id":"gcp.cost_by_service","title":"Show Google Cloud cost by service","summary":"Show gross cost, credits, and net cost per Google Cloud service over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend.","description":"Show gross cost, credits, and net cost per Google Cloud service over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum services to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Last 30 days by service","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"limit":50,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_by_sku","title":"Show Google Cloud cost by SKU","summary":"Show the costliest SKUs over a recent window with their billed usage quantity, read from the Cloud Billing export in BigQuery. This is the breakdown that names what a spend increase actually bought.","description":"Show the costliest SKUs over a recent window with their billed usage quantity, read from the Cloud Billing export in BigQuery. This is the breakdown that names what a spend increase actually bought.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum SKUs to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Costliest SKUs last 7 days","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"limit":25,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_daily_trend","title":"Show the Google Cloud daily cost trend","summary":"Show net cost per day over a recent window, newest first, read from the Cloud Billing export in BigQuery. This is the series that dates a spend increase before the by-SKU breakdown names it.","description":"Show net cost per day over a recent window, newest first, read from the Cloud Billing export in BigQuery. This is the series that dates a spend increase before the by-SKU breakdown names it.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","The most recent days are still settling and typically read low."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":90,"description":"Maximum days to return.","validation":{"min":1,"max":400}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the trend to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Daily spend over the last 30 days","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_export_freshness","title":"Check Cloud Billing export freshness","summary":"Check how current the Cloud Billing export in BigQuery is — its newest export time, that lag in hours, the usage period it covers, and the row count in the window. Run this before trusting a cost number that looks too low.","description":"Check how current the Cloud Billing export in BigQuery is — its newest export time, that lag in hours, the usage period it covers, and the row count in the window. Run this before trusting a cost number that looks too low.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":7,"description":"Recent usage window in days to summarize.","validation":{"min":1,"max":400}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}}],"examples":[{"title":"Export lag over the last week","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.2.0","content_hash":"sha256:a6b9869a9ef59734bd2d325745dc66541ed3cc617a9675acf52e3b925ca7dc17","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-billing/0.2.0/a6b9869a9ef59734bd2d325745dc66541ed3cc617a9675acf52e3b925ca7dc17/pack.tar.gz","actions":[{"id":"gcp.billing_accounts","title":"gcloud billing accounts list","summary":"List Cloud Billing accounts the runner's credentials can see, with currency, open state, and parent organization.","description":"List Cloud Billing accounts the runner's credentials can see, with currency, open state, and parent organization.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing API pagination.","Returned accounts are capped by limit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum billing accounts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Visible billing accounts","args":{"limit":100}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","accounts","list","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.billing_budgets","title":"gcloud billing budgets list","summary":"List budgets on one Cloud Billing account, with their amounts, threshold rules, and the projects or services each one filters.","description":"List budgets on one Cloud Billing account, with their amounts, threshold rules, and the projects or services each one filters.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing Budget API pagination.","Returned budgets are capped by limit.","A budget states its threshold, not current spend; the cost actions report spend."],"args":[{"name":"billing_account","type":"string","required":true,"description":"Billing account ID, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum budgets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Budgets and thresholds on one account","args":{"billing_account":"01B678-5ED3E1-AD1F9F","limit":100}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","budgets","list","--billing-account={{ args.billing_account }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.billing_projects","title":"gcloud billing projects list","summary":"List projects billed to one Cloud Billing account, with each project's billing-enabled state.","description":"List projects billed to one Cloud Billing account, with each project's billing-enabled state.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing API pagination.","Returned projects are capped by limit."],"args":[{"name":"billing_account","type":"string","required":true,"description":"Billing account ID, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum projects to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Projects on one billing account","args":{"billing_account":"01B678-5ED3E1-AD1F9F","limit":200}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","projects","list","--billing-account={{ args.billing_account }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.cost_by_project","title":"Show Google Cloud cost by project","summary":"Show gross cost, credits, and net cost per project over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend. Charges that carry no project, such as support, group as (unattributed).","description":"Show gross cost, credits, and net cost per project over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend. Charges that carry no project, such as support, group as (unattributed).","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum projects to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Last 30 days by project","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"limit":50,"project":"example-prod"}},{"title":"Compute Engine spend split by project","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"project":"example-prod","service":"Compute Engine"}}],"search_terms":[]},{"id":"gcp.cost_by_service","title":"Show Google Cloud cost by service","summary":"Show gross cost, credits, and net cost per Google Cloud service over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend.","description":"Show gross cost, credits, and net cost per Google Cloud service over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum services to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Last 30 days by service","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"limit":50,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_by_sku","title":"Show Google Cloud cost by SKU","summary":"Show the costliest SKUs over a recent window with their billed usage quantity, read from the Cloud Billing export in BigQuery. This is the breakdown that names what a spend increase actually bought.","description":"Show the costliest SKUs over a recent window with their billed usage quantity, read from the Cloud Billing export in BigQuery. This is the breakdown that names what a spend increase actually bought.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum SKUs to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Costliest SKUs last 7 days","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"limit":25,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_daily_trend","title":"Show the Google Cloud daily cost trend","summary":"Show net cost per day over a recent window, newest first, read from the Cloud Billing export in BigQuery. This is the series that dates a spend increase before the by-SKU breakdown names it.","description":"Show net cost per day over a recent window, newest first, read from the Cloud Billing export in BigQuery. This is the series that dates a spend increase before the by-SKU breakdown names it.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","The most recent days are still settling and typically read low."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":90,"description":"Maximum days to return.","validation":{"min":1,"max":400}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the trend to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Daily spend over the last 30 days","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_export_freshness","title":"Check Cloud Billing export freshness","summary":"Check how current the Cloud Billing export in BigQuery is — its newest export time, that lag in hours, the usage period it covers, and the row count in the window. Run this before trusting a cost number that looks too low.","description":"Check how current the Cloud Billing export in BigQuery is — its newest export time, that lag in hours, the usage period it covers, and the row count in the window. Run this before trusting a cost number that looks too low.","kind":"script","risk":"low","side_effects":["One gcloud token read, one table lookup that resolves the standard or detailed export, and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":7,"description":"Recent usage window in days to summarize.","validation":{"min":1,"max":400}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}}],"examples":[{"title":"Export lag over the last week","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"project":"example-prod"}}],"search_terms":[]}]},{"version":"0.1.0","content_hash":"sha256:ded4905d6f907293a62581e95123d5fb6159caf67367d6186edb0fc21827af7b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-billing/0.1.0/ded4905d6f907293a62581e95123d5fb6159caf67367d6186edb0fc21827af7b/pack.tar.gz","actions":[{"id":"gcp.billing_accounts","title":"gcloud billing accounts list","summary":"List Cloud Billing accounts the runner's credentials can see, with currency, open state, and parent organization.","description":"List Cloud Billing accounts the runner's credentials can see, with currency, open state, and parent organization.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing API pagination.","Returned accounts are capped by limit."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum billing accounts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Visible billing accounts","args":{"limit":100}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","accounts","list","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.billing_budgets","title":"gcloud billing budgets list","summary":"List budgets on one Cloud Billing account, with their amounts, threshold rules, and the projects or services each one filters.","description":"List budgets on one Cloud Billing account, with their amounts, threshold rules, and the projects or services each one filters.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing Budget API pagination.","Returned budgets are capped by limit.","A budget states its threshold, not current spend; the cost actions report spend."],"args":[{"name":"billing_account","type":"string","required":true,"description":"Billing account ID, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum budgets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Budgets and thresholds on one account","args":{"billing_account":"01B678-5ED3E1-AD1F9F","limit":100}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","budgets","list","--billing-account={{ args.billing_account }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.billing_projects","title":"gcloud billing projects list","summary":"List projects billed to one Cloud Billing account, with each project's billing-enabled state.","description":"List projects billed to one Cloud Billing account, with each project's billing-enabled state.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Billing API pagination.","Returned projects are capped by limit."],"args":[{"name":"billing_account","type":"string","required":true,"description":"Billing account ID, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum projects to return.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Projects on one billing account","args":{"billing_account":"01B678-5ED3E1-AD1F9F","limit":200}}],"search_terms":[],"command":{"binary":"gcloud","argv":["billing","projects","list","--billing-account={{ args.billing_account }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.cost_by_project","title":"Show Google Cloud cost by project","summary":"Show gross cost, credits, and net cost per project over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend. Charges that carry no project, such as support, group as (unattributed).","description":"Show gross cost, credits, and net cost per project over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend. Charges that carry no project, such as support, group as (unattributed).","kind":"script","risk":"low","side_effects":["One gcloud token read and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum projects to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Last 30 days by project","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"limit":50,"project":"example-prod"}},{"title":"Compute Engine spend split by project","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"project":"example-prod","service":"Compute Engine"}}],"search_terms":[]},{"id":"gcp.cost_by_service","title":"Show Google Cloud cost by service","summary":"Show gross cost, credits, and net cost per Google Cloud service over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend.","description":"Show gross cost, credits, and net cost per Google Cloud service over a recent window, read from the Cloud Billing export in BigQuery and ordered by the largest net spend.","kind":"script","risk":"low","side_effects":["One gcloud token read and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum services to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Last 30 days by service","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"limit":50,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_by_sku","title":"Show Google Cloud cost by SKU","summary":"Show the costliest SKUs over a recent window with their billed usage quantity, read from the Cloud Billing export in BigQuery. This is the breakdown that names what a spend increase actually bought.","description":"Show the costliest SKUs over a recent window with their billed usage quantity, read from the Cloud Billing export in BigQuery. This is the breakdown that names what a spend increase actually bought.","kind":"script","risk":"low","side_effects":["One gcloud token read and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","Recent days are still settling, so the window is an estimate rather than the invoice."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Maximum SKUs to return.","validation":{"min":1,"max":1000}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the window to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Costliest SKUs last 7 days","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"limit":25,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_daily_trend","title":"Show the Google Cloud daily cost trend","summary":"Show net cost per day over a recent window, newest first, read from the Cloud Billing export in BigQuery. This is the series that dates a spend increase before the by-SKU breakdown names it.","description":"Show net cost per day over a recent window, newest first, read from the Cloud Billing export in BigQuery. This is the series that dates a spend increase before the by-SKU breakdown names it.","kind":"script","risk":"low","side_effects":["One gcloud token read and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb.","The most recent days are still settling and typically read low."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":30,"description":"Recent usage window in days.","validation":{"min":1,"max":400}},{"name":"limit","type":"integer","required":false,"default":90,"description":"Maximum days to return.","validation":{"min":1,"max":400}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}},{"name":"service","type":"string","required":false,"default":"","description":"Optional exact service description to restrict the trend to, such as Compute Engine.","validation":{"pattern":"^[ -~]*$","max_length":256}}],"examples":[{"title":"Daily spend over the last 30 days","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":30,"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.cost_export_freshness","title":"Check Cloud Billing export freshness","summary":"Check how current the Cloud Billing export in BigQuery is — its newest export time, that lag in hours, the usage period it covers, and the row count in the window. Run this before trusting a cost number that looks too low.","description":"Check how current the Cloud Billing export in BigQuery is — its newest export time, that lag in hours, the usage period it covers, and the row count in the window. Run this before trusting a cost number that looks too low.","kind":"script","risk":"low","side_effects":["One gcloud token read and one BigQuery query billed by bytes scanned.","The query fails rather than scanning past max_scan_gb."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project that holds the billing export dataset and runs the query.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"dataset","type":"string","required":true,"description":"BigQuery dataset holding the billing export tables.","validation":{"pattern":"^[A-Za-z0-9_]+$","max_length":1024}},{"name":"billing_account","type":"string","required":true,"description":"Billing account ID whose export table is queried, such as 01B678-5ED3E1-AD1F9F.","validation":{"pattern":"^[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}$"}},{"name":"days","type":"integer","required":false,"default":7,"description":"Recent usage window in days to summarize.","validation":{"min":1,"max":400}},{"name":"max_scan_gb","type":"integer","required":false,"default":20,"description":"Hard cap on BigQuery bytes billed for this query, in GiB.","validation":{"min":1,"max":200}}],"examples":[{"title":"Export lag over the last week","args":{"billing_account":"01B678-5ED3E1-AD1F9F","dataset":"billing_export","days":7,"project":"example-prod"}}],"search_terms":[]}]}]},{"id":"gcp-certificates","name":"Google Cloud certificate diagnostics","version":"0.1.1","description":"Read-only diagnostics for legacy Compute SSL certificates and Certificate Manager certificates, maps, entries, and DNS authorizations. Fixed projections omit certificate PEM, private keys, descriptions, and labels.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-certificates","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-certificates","content_hash":"sha256:2471ad19636520b3610fb02f74c4115b2146491a5e7afdfb896de8220778fe97","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-certificates/0.1.1/2471ad19636520b3610fb02f74c4115b2146491a5e7afdfb896de8220778fe97/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives gcloud and projects certificate API responses locally before they leave the runner. Authenticate gcloud before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Legacy Compute certificate reads need roles/compute.networkViewer; Certificate Manager reads need roles/certificatemanager.viewer or equivalent permissions.","Actions use mode-0600 temporary response files so gcloud failures remain distinguishable from jq failures; files are removed before exit.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed."],"verify":"gcp.managed_certificates"},"actions":[{"id":"gcp.certificate_map_entries","title":"gcloud certificate-manager maps entries list","summary":"List bounded host or primary matchers and certificates in one certificate map.","description":"List bounded host or primary matchers and certificates in one certificate map.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"map","type":"string","required":true,"description":"Certificate map ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum entries to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application certificate map","args":{"map":"app","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.certificate_maps","title":"gcloud certificate-manager maps list","summary":"List bounded Certificate Manager maps and attached load-balancer targets.","description":"List bounded Certificate Manager maps and attached load-balancer targets.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum maps to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global certificate maps","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_authorizations","title":"gcloud certificate-manager dns-authorizations list","summary":"List bounded Certificate Manager DNS authorizations and required public DNS records.","description":"List bounded Certificate Manager DNS authorizations and required public DNS records.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Returns domain-validation DNS record data.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location or '-' for all locations.","validation":{"pattern":"^(?:-|[a-z0-9][a-z0-9-]{0,62})$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum authorizations to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global DNS authorizations","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.managed_certificate_describe","title":"gcloud certificate-manager certificates describe","summary":"Show one Certificate Manager certificate's source, SANs, state, and expiry without PEM.","description":"Show one Certificate Manager certificate's source, SANs, state, and expiry without PEM.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"certificate","type":"string","required":true,"description":"Certificate Manager certificate ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Global application certificate","args":{"certificate":"app","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.managed_certificates","title":"gcloud certificate-manager certificates list","summary":"List bounded Certificate Manager certificate source, SANs, provisioning state, and expiry without PEM.","description":"List bounded Certificate Manager certificate source, SANs, provisioning state, and expiry without PEM.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location or '-' for all locations.","validation":{"pattern":"^(?:-|[a-z0-9][a-z0-9-]{0,62})$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global managed certificates","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.ssl_certificate_describe","title":"gcloud compute ssl-certificates describe","summary":"Show one legacy Compute SSL certificate's status, SANs, and expiry without PEM.","description":"Show one legacy Compute SSL certificate's status, SANs, and expiry without PEM.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"certificate","type":"string","required":true,"description":"Legacy Compute SSL certificate name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"scope","type":"string","required":true,"description":"Certificate scope.","validation":{"enum":["global","region"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region for region scope; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$","max_length":63}}],"examples":[{"title":"Global legacy certificate","args":{"certificate":"app","project":"example-prod","scope":"global"}}],"search_terms":[]},{"id":"gcp.ssl_certificates","title":"gcloud compute ssl-certificates list","summary":"List bounded legacy Compute SSL certificate status, SANs, and expiry without PEM.","description":"List bounded legacy Compute SSL certificate status, SANs, and expiry without PEM.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Legacy Compute certificates","args":{"project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:da73325336f2d11cdff984948bf6f53fe34f43f1bce873c6e01e6a6fc38f792b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-certificates/0.1.0/da73325336f2d11cdff984948bf6f53fe34f43f1bce873c6e01e6a6fc38f792b/pack.tar.gz","actions":[{"id":"gcp.certificate_map_entries","title":"gcloud certificate-manager maps entries list","summary":"List bounded host or primary matchers and certificates in one certificate map.","description":"List bounded host or primary matchers and certificates in one certificate map.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"map","type":"string","required":true,"description":"Certificate map ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum entries to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application certificate map","args":{"map":"app","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.certificate_maps","title":"gcloud certificate-manager maps list","summary":"List bounded Certificate Manager maps and attached load-balancer targets.","description":"List bounded Certificate Manager maps and attached load-balancer targets.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum maps to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global certificate maps","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_authorizations","title":"gcloud certificate-manager dns-authorizations list","summary":"List bounded Certificate Manager DNS authorizations and required public DNS records.","description":"List bounded Certificate Manager DNS authorizations and required public DNS records.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Returns domain-validation DNS record data.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location or '-' for all locations.","validation":{"pattern":"^(?:-|[a-z0-9][a-z0-9-]{0,62})$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum authorizations to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global DNS authorizations","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.managed_certificate_describe","title":"gcloud certificate-manager certificates describe","summary":"Show one Certificate Manager certificate's source, SANs, state, and expiry without PEM.","description":"Show one Certificate Manager certificate's source, SANs, state, and expiry without PEM.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"certificate","type":"string","required":true,"description":"Certificate Manager certificate ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Global application certificate","args":{"certificate":"app","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.managed_certificates","title":"gcloud certificate-manager certificates list","summary":"List bounded Certificate Manager certificate source, SANs, provisioning state, and expiry without PEM.","description":"List bounded Certificate Manager certificate source, SANs, provisioning state, and expiry without PEM.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Certificate Manager location or '-' for all locations.","validation":{"pattern":"^(?:-|[a-z0-9][a-z0-9-]{0,62})$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global managed certificates","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.ssl_certificate_describe","title":"gcloud compute ssl-certificates describe","summary":"Show one legacy Compute SSL certificate's status, SANs, and expiry without PEM.","description":"Show one legacy Compute SSL certificate's status, SANs, and expiry without PEM.","kind":"script","risk":"low","side_effects":["One read-only API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"certificate","type":"string","required":true,"description":"Legacy Compute SSL certificate name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"scope","type":"string","required":true,"description":"Certificate scope.","validation":{"enum":["global","region"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region for region scope; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$","max_length":63}}],"examples":[{"title":"Global legacy certificate","args":{"certificate":"app","project":"example-prod","scope":"global"}}],"search_terms":[]},{"id":"gcp.ssl_certificates","title":"gcloud compute ssl-certificates list","summary":"List bounded legacy Compute SSL certificate status, SANs, and expiry without PEM.","description":"List bounded legacy Compute SSL certificate status, SANs, and expiry without PEM.","kind":"script","risk":"low","side_effects":["Read-only API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Legacy Compute certificates","args":{"project":"example-prod"}}],"search_terms":[]}]}]},{"id":"gcp-cloudsql","name":"Google Cloud SQL diagnostics and recovery","version":"0.3.1","description":"Cloud SQL diagnostics for instances, databases, users, backups, operations, server CA certificates, and Query Insights query rankings, plus governed instance restart and high-availability failover. Fixed projections omit passwords, replication credentials, database-flag values, labels, descriptions, and certificate PEM. Mutations return their operation without waiting and are polled with gcp.sql_operation_describe.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-cloudsql","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-cloudsql","content_hash":"sha256:5e58f6e111b28493aa89372e6c1ca8f4eeb3865e260481f0a344312f48f9c990","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-cloudsql/0.3.1/5e58f6e111b28493aa89372e6c1ca8f4eeb3865e260481f0a344312f48f9c990/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","jq","curl"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives gcloud and projects Cloud SQL API responses locally before they leave the runner. Authenticate gcloud before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Grant least privilege for the actions you enable: reads need roles/cloudsql.viewer or equivalent; restart and failover need cloudsql.instances.restart and cloudsql.instances.failover (both in roles/cloudsql.editor).","Actions use mode-0600 temporary response files so gcloud failures remain distinguishable from jq failures; files are removed before exit.","Database query execution, log contents, auth tokens, client certificates, and credential retrieval are excluded.","gcp.sql_query_insights additionally needs roles/monitoring.viewer: Query Insights has no Cloud SQL Admin API surface, so it is read from the Cloud Monitoring API rather than gcloud. It returns Query Insights' own normalized query text, in which literals are already replaced by placeholders, and never executes a query or reads log contents.","Query Insights must be enabled on the instance (settings.insightsConfig, reported by gcp.sql_instance_describe) or the ranking is empty; shared-core tiers may not support it.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed."],"verify":"gcp.sql_instances"},"actions":[{"id":"gcp.sql_backups","title":"gcloud sql backups list","summary":"List bounded Cloud SQL backup status, type, location, version, and timing.","description":"List bounded Cloud SQL backup status, type, location, version, and timing.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum backups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database backups","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_databases","title":"gcloud sql databases list","summary":"List bounded database names, charset, collation, and SQL Server details for one instance.","description":"List bounded database names, charset, collation, and SQL Server details for one instance.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum databases to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application databases","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_instance_describe","title":"gcloud sql instances describe","summary":"Show one Cloud SQL instance's engine, HA, networking, backup, maintenance, and capacity summary.","description":"Show one Cloud SQL instance's engine, HA, networking, backup, maintenance, and capacity summary.","kind":"script","risk":"low","side_effects":["One read-only Cloud SQL API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Application database","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_instance_failover","title":"gcloud sql instances failover","summary":"Fail one high-availability (REGIONAL) Cloud SQL primary over to its standby in the secondary zone. Connections are dropped and writes pause until the standby is serving; only works on an instance with REGIONAL availability. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","description":"Fail one high-availability (REGIONAL) Cloud SQL primary over to its standby in the secondary zone. Connections are dropped and writes pause until the standby is serving; only works on an instance with REGIONAL availability. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","kind":"script","risk":"high","side_effects":["All connections are dropped; the database is briefly unavailable while the standby takes over.","The primary and secondary zones swap; clients reconnect to the same address.","Fails on an instance without REGIONAL (high-availability) configuration."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Fail over an HA primary during a zone incident","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":["promote standby","zone outage","HA failover"]},{"id":"gcp.sql_instance_restart","title":"gcloud sql instances restart","summary":"Restart one Cloud SQL instance. Every connection is dropped and the database is unavailable until the restart completes. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","description":"Restart one Cloud SQL instance. Every connection is dropped and the database is unavailable until the restart completes. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","kind":"script","risk":"high","side_effects":["All database connections are dropped; the instance is unavailable during the restart.","Returns the pending operation without waiting for completion.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Restart a stuck application database","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":["restart database","hung database","recover instance"]},{"id":"gcp.sql_instances","title":"gcloud sql instances list","summary":"List bounded Cloud SQL engine, HA, networking, backup, maintenance, and capacity summaries.","description":"List bounded Cloud SQL engine, HA, networking, backup, maintenance, and capacity summaries.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum instances to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project SQL instances","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_operation_describe","title":"gcloud sql operations describe","summary":"Show one Cloud SQL operation's type, target, status, timing, and error codes.","description":"Show one Cloud SQL operation's type, target, status, timing, and error codes.","kind":"script","risk":"low","side_effects":["One read-only Cloud SQL API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"operation","type":"string","required":true,"description":"Cloud SQL operation ID.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9])?$","max_length":128}}],"examples":[{"title":"Inspect a failed operation","args":{"operation":"operation-123","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_operations","title":"gcloud sql operations list","summary":"List bounded recent Cloud SQL operation type, target, status, timing, and error codes.","description":"List bounded recent Cloud SQL operation type, target, status, timing, and error codes.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum operations to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database operations","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_query_insights","title":"Show the top Cloud SQL queries by Query Insights metric","summary":"Show the normalized PostgreSQL queries ranked highest by one Query Insights metric over a recent window — total execution, I/O or lock time, rows or shared-block accesses, or p50/p95/p99 latency. This is the read that names which query is spending the instance's time.","description":"Show the normalized PostgreSQL queries ranked highest by one Query Insights metric over a recent window — total execution, I/O or lock time, rows or shared-block accesses, or p50/p95/p99 latency. This is the read that names which query is spending the instance's time.","kind":"script","risk":"low","side_effects":["One gcloud token read and read-only Cloud Monitoring API pagination.","Query text is returned normalized, with literals replaced by placeholders.","Ranking is client-side, so ranking_complete reports whether every series was read.","Uses a mode-0700 temporary directory and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"database","type":"string","required":false,"default":"","description":"Optional database name to restrict the ranking to. Omit to rank across every database on the instance.","validation":{"pattern":"^[A-Za-z0-9_-]*$","max_length":63}},{"name":"metric","type":"string","required":false,"default":"execution_time","description":"Query Insights metric to rank by. Time metrics and latencies are microseconds; row and block metrics are counts.","validation":{"enum":["execution_time","io_time","lock_time","row_count","shared_blk_access_count","latency_p50","latency_p95","latency_p99"]}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent window in minutes, aligned as a single period so each query yields one comparable value.","validation":{"min":5,"max":1440}},{"name":"top_n","type":"integer","required":false,"default":10,"description":"Maximum ranked queries to return.","validation":{"min":1,"max":100}}],"examples":[{"title":"Queries burning the most execution time this hour","args":{"instance":"app-db","metric":"execution_time","project":"example-prod","top_n":10,"window_minutes":60}},{"title":"Worst p99 latency over the last day for one database","args":{"database":"app","instance":"app-db","metric":"latency_p99","project":"example-prod","top_n":20,"window_minutes":1440}}],"search_terms":[]},{"id":"gcp.sql_server_ca_certs","title":"gcloud sql ssl server-ca-certs list","summary":"List bounded Cloud SQL server CA identity, type, fingerprint, and expiry without certificate PEM.","description":"List bounded Cloud SQL server CA identity, type, fingerprint, and expiry without certificate PEM.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum server CA certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database server CAs","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_users","title":"gcloud sql users list","summary":"List bounded Cloud SQL user identities, hosts, types, and password-policy state without passwords.","description":"List bounded Cloud SQL user identities, hosts, types, and password-policy state without passwords.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Returns database user identities.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum users to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database users","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.3.0","content_hash":"sha256:45cbc52c0088f28a747d80cb2c71879232cb97e95aab65e15efcdd4840c30b32","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-cloudsql/0.3.0/45cbc52c0088f28a747d80cb2c71879232cb97e95aab65e15efcdd4840c30b32/pack.tar.gz","actions":[{"id":"gcp.sql_backups","title":"gcloud sql backups list","summary":"List bounded Cloud SQL backup status, type, location, version, and timing.","description":"List bounded Cloud SQL backup status, type, location, version, and timing.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum backups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database backups","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_databases","title":"gcloud sql databases list","summary":"List bounded database names, charset, collation, and SQL Server details for one instance.","description":"List bounded database names, charset, collation, and SQL Server details for one instance.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum databases to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application databases","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_instance_describe","title":"gcloud sql instances describe","summary":"Show one Cloud SQL instance's engine, HA, networking, backup, maintenance, and capacity summary.","description":"Show one Cloud SQL instance's engine, HA, networking, backup, maintenance, and capacity summary.","kind":"script","risk":"low","side_effects":["One read-only Cloud SQL API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Application database","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_instance_failover","title":"gcloud sql instances failover","summary":"Fail one high-availability (REGIONAL) Cloud SQL primary over to its standby in the secondary zone. Connections are dropped and writes pause until the standby is serving; only works on an instance with REGIONAL availability. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","description":"Fail one high-availability (REGIONAL) Cloud SQL primary over to its standby in the secondary zone. Connections are dropped and writes pause until the standby is serving; only works on an instance with REGIONAL availability. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","kind":"script","risk":"high","side_effects":["All connections are dropped; the database is briefly unavailable while the standby takes over.","The primary and secondary zones swap; clients reconnect to the same address.","Fails on an instance without REGIONAL (high-availability) configuration."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Fail over an HA primary during a zone incident","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":["promote standby","zone outage","HA failover"]},{"id":"gcp.sql_instance_restart","title":"gcloud sql instances restart","summary":"Restart one Cloud SQL instance. Every connection is dropped and the database is unavailable until the restart completes. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","description":"Restart one Cloud SQL instance. Every connection is dropped and the database is unavailable until the restart completes. Returns the Cloud SQL operation immediately without waiting; poll gcp.sql_operation_describe until it reports DONE.","kind":"script","risk":"high","side_effects":["All database connections are dropped; the instance is unavailable during the restart.","Returns the pending operation without waiting for completion.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Restart a stuck application database","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":["restart database","hung database","recover instance"]},{"id":"gcp.sql_instances","title":"gcloud sql instances list","summary":"List bounded Cloud SQL engine, HA, networking, backup, maintenance, and capacity summaries.","description":"List bounded Cloud SQL engine, HA, networking, backup, maintenance, and capacity summaries.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum instances to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project SQL instances","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_operation_describe","title":"gcloud sql operations describe","summary":"Show one Cloud SQL operation's type, target, status, timing, and error codes.","description":"Show one Cloud SQL operation's type, target, status, timing, and error codes.","kind":"script","risk":"low","side_effects":["One read-only Cloud SQL API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"operation","type":"string","required":true,"description":"Cloud SQL operation ID.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9])?$","max_length":128}}],"examples":[{"title":"Inspect a failed operation","args":{"operation":"operation-123","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_operations","title":"gcloud sql operations list","summary":"List bounded recent Cloud SQL operation type, target, status, timing, and error codes.","description":"List bounded recent Cloud SQL operation type, target, status, timing, and error codes.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum operations to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database operations","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_query_insights","title":"Show the top Cloud SQL queries by Query Insights metric","summary":"Show the normalized PostgreSQL queries ranked highest by one Query Insights metric over a recent window — total execution, I/O or lock time, rows or shared-block accesses, or p50/p95/p99 latency. This is the read that names which query is spending the instance's time.","description":"Show the normalized PostgreSQL queries ranked highest by one Query Insights metric over a recent window — total execution, I/O or lock time, rows or shared-block accesses, or p50/p95/p99 latency. This is the read that names which query is spending the instance's time.","kind":"script","risk":"low","side_effects":["One gcloud token read and read-only Cloud Monitoring API pagination.","Query text is returned normalized, with literals replaced by placeholders.","Ranking is client-side, so ranking_complete reports whether every series was read.","Uses a mode-0700 temporary directory and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"database","type":"string","required":false,"default":"","description":"Optional database name to restrict the ranking to. Omit to rank across every database on the instance.","validation":{"pattern":"^[A-Za-z0-9_-]*$","max_length":63}},{"name":"metric","type":"string","required":false,"default":"execution_time","description":"Query Insights metric to rank by. Time metrics and latencies are microseconds; row and block metrics are counts.","validation":{"enum":["execution_time","io_time","lock_time","row_count","shared_blk_access_count","latency_p50","latency_p95","latency_p99"]}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent window in minutes, aligned as a single period so each query yields one comparable value.","validation":{"min":5,"max":1440}},{"name":"top_n","type":"integer","required":false,"default":10,"description":"Maximum ranked queries to return.","validation":{"min":1,"max":100}}],"examples":[{"title":"Queries burning the most execution time this hour","args":{"instance":"app-db","metric":"execution_time","project":"example-prod","top_n":10,"window_minutes":60}},{"title":"Worst p99 latency over the last day for one database","args":{"database":"app","instance":"app-db","metric":"latency_p99","project":"example-prod","top_n":20,"window_minutes":1440}}],"search_terms":[]},{"id":"gcp.sql_server_ca_certs","title":"gcloud sql ssl server-ca-certs list","summary":"List bounded Cloud SQL server CA identity, type, fingerprint, and expiry without certificate PEM.","description":"List bounded Cloud SQL server CA identity, type, fingerprint, and expiry without certificate PEM.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum server CA certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database server CAs","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_users","title":"gcloud sql users list","summary":"List bounded Cloud SQL user identities, hosts, types, and password-policy state without passwords.","description":"List bounded Cloud SQL user identities, hosts, types, and password-policy state without passwords.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Returns database user identities.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum users to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database users","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]}]},{"version":"0.1.0","content_hash":"sha256:decb79e17a030889b09ec7e059e2e3c17b82526c3db3f43c82fe1eae53d3aec2","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-cloudsql/0.1.0/decb79e17a030889b09ec7e059e2e3c17b82526c3db3f43c82fe1eae53d3aec2/pack.tar.gz","actions":[{"id":"gcp.sql_backups","title":"gcloud sql backups list","summary":"List bounded Cloud SQL backup status, type, location, version, and timing.","description":"List bounded Cloud SQL backup status, type, location, version, and timing.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum backups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database backups","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_databases","title":"gcloud sql databases list","summary":"List bounded database names, charset, collation, and SQL Server details for one instance.","description":"List bounded database names, charset, collation, and SQL Server details for one instance.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum databases to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application databases","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_instance_describe","title":"gcloud sql instances describe","summary":"Show one Cloud SQL instance's engine, HA, networking, backup, maintenance, and capacity summary.","description":"Show one Cloud SQL instance's engine, HA, networking, backup, maintenance, and capacity summary.","kind":"script","risk":"low","side_effects":["One read-only Cloud SQL API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}}],"examples":[{"title":"Application database","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_instances","title":"gcloud sql instances list","summary":"List bounded Cloud SQL engine, HA, networking, backup, maintenance, and capacity summaries.","description":"List bounded Cloud SQL engine, HA, networking, backup, maintenance, and capacity summaries.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum instances to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project SQL instances","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_operation_describe","title":"gcloud sql operations describe","summary":"Show one Cloud SQL operation's type, target, status, timing, and error codes.","description":"Show one Cloud SQL operation's type, target, status, timing, and error codes.","kind":"script","risk":"low","side_effects":["One read-only Cloud SQL API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"operation","type":"string","required":true,"description":"Cloud SQL operation ID.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9])?$","max_length":128}}],"examples":[{"title":"Inspect a failed operation","args":{"operation":"operation-123","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_operations","title":"gcloud sql operations list","summary":"List bounded recent Cloud SQL operation type, target, status, timing, and error codes.","description":"List bounded recent Cloud SQL operation type, target, status, timing, and error codes.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum operations to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database operations","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_server_ca_certs","title":"gcloud sql ssl server-ca-certs list","summary":"List bounded Cloud SQL server CA identity, type, fingerprint, and expiry without certificate PEM.","description":"List bounded Cloud SQL server CA identity, type, fingerprint, and expiry without certificate PEM.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum server CA certificates to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database server CAs","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.sql_users","title":"gcloud sql users list","summary":"List bounded Cloud SQL user identities, hosts, types, and password-policy state without passwords.","description":"List bounded Cloud SQL user identities, hosts, types, and password-policy state without passwords.","kind":"script","risk":"low","side_effects":["Read-only Cloud SQL API pagination.","Returns database user identities.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"instance","type":"string","required":true,"description":"Cloud SQL instance ID.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,96}[a-z0-9])?$","max_length":98}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum users to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application database users","args":{"instance":"app-db","project":"example-prod"}}],"search_terms":[]}]}]},{"id":"gcp-compute","name":"Google Cloud Compute diagnostics and recovery","version":"0.2.3","description":"Google Cloud Compute diagnostics plus governed recovery mutations: VM instance and managed-instance-group reads, instance start/stop/reset/delete, and MIG resize. Load-balancer diagnostics live in the gcp-load-balancing pack. Every action names the target project and zone or region explicitly and uses fixed gcloud commands; mutations return their operation without waiting and are polled with gcp.operation_status.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-compute","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-compute","content_hash":"sha256:f8ac679f17573a20cb921df8a4462f218c89de082be5e0893862bac16cdc5110","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-compute/0.2.3/f8ac679f17573a20cb921df8a4462f218c89de082be5e0893862bac16cdc5110/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the gcloud CLI on the runner host. Authenticate gcloud with a workload identity, attached service account, service-account credential, or operator configuration before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional path to a credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Any credential/config env you set must be allowlisted in the runner's `execution.inherit_env`; attached service accounts and workload identity need no credential env.","For a credential file, populate a dedicated `CLOUDSDK_CONFIG` with `gcloud auth login --cred-file=...` or set `CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE`; ordinary gcloud commands do not authenticate from GOOGLE_APPLICATION_CREDENTIALS.","Grant least privilege for the actions you enable: reads need Compute Viewer-equivalent permissions plus compute.instances.getSerialPortOutput for serial diagnostics; the lifecycle and resize mutations need roles/compute.instanceAdmin.v1-equivalent permissions on the target instances and groups.","This is a remote-target client pack and is never host-auto-suggested merely because gcloud is installed.","All actions pass --quiet and an explicit --project, so ambient project configuration cannot redirect a request."],"verify":"gcp.instance_describe"},"actions":[{"id":"gcp.instance_delete","title":"gcloud compute instances delete","summary":"Permanently delete one Compute Engine instance from its zone. Cannot be undone: local SSDs are always destroyed and attached disks marked auto-delete are destroyed with it. Fails on an instance with deletion protection enabled. Waits until the deletion completes and reports the deleted instance URL on stderr.","description":"Permanently delete one Compute Engine instance from its zone. Cannot be undone: local SSDs are always destroyed and attached disks marked auto-delete are destroyed with it. Fails on an instance with deletion protection enabled. Waits until the deletion completes and reports the deleted instance URL on stderr.","kind":"exec","risk":"critical","side_effects":["Instance is shut down and DELETED; this is irreversible.","Local SSD data is always destroyed; auto-delete disks (boot disk by default) are destroyed too.","Instance IPs are released; a managed instance group may recreate a deleted member."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Delete a decommissioned VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["terminate VM","decommission instance","remove instance"],"command":{"binary":"gcloud","argv":["compute","instances","delete","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json","--quiet"]}},{"id":"gcp.instance_describe","title":"gcloud compute instances describe","summary":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","description":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Does not return instance metadata values or serial output."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Describe a production VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["compute","instances","describe","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,id,status,zone,machineType,creationTimestamp,lastStartTimestamp,lastStopTimestamp,lastSuspendedTimestamp,cpuPlatform,hostname,deletionProtection,canIpForward,networkInterfaces,disks,scheduling,serviceAccounts,tags,labels,metadata.fingerprint)","--quiet"]}},{"id":"gcp.instance_reset","title":"gcloud compute instances reset","summary":"Reset one Compute Engine instance in its zone — a hard power cycle for a hung VM. The guest OS gets no shutdown signal, so unflushed writes are lost; the instance keeps its IPs and disks. Waits for the reset to be issued and returns the instance's lifecycle state.","description":"Reset one Compute Engine instance in its zone — a hard power cycle for a hung VM. The guest OS gets no shutdown signal, so unflushed writes are lost; the instance keeps its IPs and disks. Waits for the reset to be issued and returns the instance's lifecycle state.","kind":"exec","risk":"high","side_effects":["Immediate hard reboot with no guest shutdown; in-memory and unflushed data are lost.","Connections are dropped until the instance finishes rebooting.","The instance keeps its IPs, disks, and metadata."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Power-cycle a hung VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["hard reboot","hung VM","power cycle"],"command":{"binary":"gcloud","argv":["compute","instances","reset","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,status,zone,lastStartTimestamp,lastStopTimestamp)","--quiet"]}},{"id":"gcp.instance_serial_output","title":"gcloud compute instances get-serial-port-output","summary":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","description":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","kind":"exec","risk":"medium","side_effects":["One read-only Compute Engine API call.","Returns guest-written serial output and may expose data the guest logged."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"port","type":"integer","required":false,"default":1,"description":"Serial port number.","validation":{"min":1,"max":4}},{"name":"start","type":"integer","required":false,"default":0,"description":"Zero-based byte offset at which to start reading.","validation":{"min":0,"max":9007199254740991}}],"examples":[{"title":"Read the primary boot console","args":{"instance":"api-01","port":1,"project":"example-prod","start":0,"zone":"us-central1-a"}}],"search_terms":["boot failure","startup log","VM console"],"command":{"binary":"gcloud","argv":["compute","instances","get-serial-port-output","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--port={{ args.port }}","--start={{ args.start }}","--quiet"]}},{"id":"gcp.instance_start","title":"gcloud compute instances start","summary":"Start one stopped Compute Engine instance in its zone. Returns the zonal operation immediately without waiting for the boot; poll gcp.operation_status until it reports DONE.","description":"Start one stopped Compute Engine instance in its zone. Returns the zonal operation immediately without waiting for the boot; poll gcp.operation_status until it reports DONE.","kind":"exec","risk":"high","side_effects":["Instance begins booting; machine-type billing resumes.","An ephemeral external IPv4 changes across a stop/start unless a static address is reserved."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Start a stopped VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["power on","boot VM","recover stopped instance"],"command":{"binary":"gcloud","argv":["compute","instances","start","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--async","--format=json(name,status,operationType,progress,insertTime,startTime,endTime,targetLink,zone,region,error,warnings,httpErrorStatusCode,httpErrorMessage)","--quiet"]}},{"id":"gcp.instance_stop","title":"gcloud compute instances stop","summary":"Stop one running Compute Engine instance in its zone. The guest OS is shut down and every workload on the instance goes offline until it is started again. Returns the zonal operation immediately without waiting for the shutdown; poll gcp.operation_status until it reports DONE.","description":"Stop one running Compute Engine instance in its zone. The guest OS is shut down and every workload on the instance goes offline until it is started again. Returns the zonal operation immediately without waiting for the shutdown; poll gcp.operation_status until it reports DONE.","kind":"exec","risk":"high","side_effects":["All workloads on the instance go offline; connections are dropped.","An ephemeral external IPv4 is released; a new one is assigned on start.","Machine-type billing stops; attached disks keep billing and their data."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Stop a misbehaving VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["power off","shut down VM","take instance offline"],"command":{"binary":"gcloud","argv":["compute","instances","stop","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--async","--format=json(name,status,operationType,progress,insertTime,startTime,endTime,targetLink,zone,region,error,warnings,httpErrorStatusCode,httpErrorMessage)","--quiet"]}},{"id":"gcp.mig_health","title":"gcloud compute instance-groups managed describe (health summary)","summary":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","description":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns group configuration and status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"Show a zonal MIG health summary","args":{"group":"workers","location":"us-central1-a","project":"example-prod","scope":"zone"}}],"search_terms":["managed instance group unhealthy","MIG rollout","MIG stable"]},{"id":"gcp.mig_instances","title":"gcloud compute instance-groups managed list-instances","summary":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","description":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Returned managed-instance records are capped at 500."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"List instances in a regional MIG","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region"}}],"search_terms":[]},{"id":"gcp.mig_resize","title":"gcloud compute instance-groups managed resize","summary":"Resize one zonal or regional managed instance group to an exact instance count. Scaling down deletes surplus instances; size 0 deletes every instance and the group serves nothing until scaled back up. Fails on a group managed by an autoscaler. Waits for the resize to be accepted and returns the group's new target size; instances converge asynchronously (watch with gcp.mig_health).","description":"Resize one zonal or regional managed instance group to an exact instance count. Scaling down deletes surplus instances; size 0 deletes every instance and the group serves nothing until scaled back up. Fails on a group managed by an autoscaler. Waits for the resize to be accepted and returns the group's new target size; instances converge asynchronously (watch with gcp.mig_health).","kind":"script","risk":"high","side_effects":["Scaling down DELETES surplus instances and their auto-delete disks; size 0 empties the group.","Scaling up creates instances from the group's current template; billing changes with the size.","Rejected when an autoscaler manages the group's size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"size","type":"integer","required":true,"description":"Exact target number of instances; 0 deletes every instance in the group.","validation":{"min":0,"max":1000}}],"examples":[{"title":"Scale a regional MIG to 3 instances","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region","size":3}}],"search_terms":["scale out","scale in","add capacity","drain group"]},{"id":"gcp.operation_status","title":"gcloud compute operations describe","summary":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","description":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns operation status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"operation","type":"string","required":true,"description":"Compute Engine operation name.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{0,126}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Operation scope.","validation":{"enum":["global","region","zone"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region or zone for a scoped operation; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$"}}],"examples":[{"title":"Check a zonal operation","args":{"location":"us-central1-a","operation":"operation-1712345678901-abcdef","project":"example-prod","scope":"zone"}}],"search_terms":[]}],"previous_versions":[{"version":"0.2.2","content_hash":"sha256:f70ea222906ef7af3cdfcdec6323386c9cc9c2bab533ddfa45b240e67293effd","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-compute/0.2.2/f70ea222906ef7af3cdfcdec6323386c9cc9c2bab533ddfa45b240e67293effd/pack.tar.gz","actions":[{"id":"gcp.instance_delete","title":"gcloud compute instances delete","summary":"Permanently delete one Compute Engine instance from its zone. Cannot be undone: local SSDs are always destroyed and attached disks marked auto-delete are destroyed with it. Fails on an instance with deletion protection enabled. Waits until the deletion completes and reports the deleted instance URL on stderr.","description":"Permanently delete one Compute Engine instance from its zone. Cannot be undone: local SSDs are always destroyed and attached disks marked auto-delete are destroyed with it. Fails on an instance with deletion protection enabled. Waits until the deletion completes and reports the deleted instance URL on stderr.","kind":"exec","risk":"critical","side_effects":["Instance is shut down and DELETED; this is irreversible.","Local SSD data is always destroyed; auto-delete disks (boot disk by default) are destroyed too.","Instance IPs are released; a managed instance group may recreate a deleted member."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Delete a decommissioned VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["terminate VM","decommission instance","remove instance"],"command":{"binary":"gcloud","argv":["compute","instances","delete","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json","--quiet"]}},{"id":"gcp.instance_describe","title":"gcloud compute instances describe","summary":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","description":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Does not return instance metadata values or serial output."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Describe a production VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["compute","instances","describe","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,id,status,zone,machineType,creationTimestamp,lastStartTimestamp,lastStopTimestamp,lastSuspendedTimestamp,cpuPlatform,hostname,deletionProtection,canIpForward,networkInterfaces,disks,scheduling,serviceAccounts,tags,labels,metadata.fingerprint)","--quiet"]}},{"id":"gcp.instance_reset","title":"gcloud compute instances reset","summary":"Reset one Compute Engine instance in its zone — a hard power cycle for a hung VM. The guest OS gets no shutdown signal, so unflushed writes are lost; the instance keeps its IPs and disks. Waits for the reset to be issued and returns the instance's lifecycle state.","description":"Reset one Compute Engine instance in its zone — a hard power cycle for a hung VM. The guest OS gets no shutdown signal, so unflushed writes are lost; the instance keeps its IPs and disks. Waits for the reset to be issued and returns the instance's lifecycle state.","kind":"exec","risk":"high","side_effects":["Immediate hard reboot with no guest shutdown; in-memory and unflushed data are lost.","Connections are dropped until the instance finishes rebooting.","The instance keeps its IPs, disks, and metadata."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Power-cycle a hung VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["hard reboot","hung VM","power cycle"],"command":{"binary":"gcloud","argv":["compute","instances","reset","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,status,zone,lastStartTimestamp,lastStopTimestamp)","--quiet"]}},{"id":"gcp.instance_serial_output","title":"gcloud compute instances get-serial-port-output","summary":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","description":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns guest-written serial output and may expose data the guest logged."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"port","type":"integer","required":false,"default":1,"description":"Serial port number.","validation":{"min":1,"max":4}},{"name":"start","type":"integer","required":false,"default":0,"description":"Zero-based byte offset at which to start reading.","validation":{"min":0,"max":9007199254740991}}],"examples":[{"title":"Read the primary boot console","args":{"instance":"api-01","port":1,"project":"example-prod","start":0,"zone":"us-central1-a"}}],"search_terms":["boot failure","startup log","VM console"],"command":{"binary":"gcloud","argv":["compute","instances","get-serial-port-output","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--port={{ args.port }}","--start={{ args.start }}","--quiet"]}},{"id":"gcp.instance_start","title":"gcloud compute instances start","summary":"Start one stopped Compute Engine instance in its zone. Returns the zonal operation immediately without waiting for the boot; poll gcp.operation_status until it reports DONE.","description":"Start one stopped Compute Engine instance in its zone. Returns the zonal operation immediately without waiting for the boot; poll gcp.operation_status until it reports DONE.","kind":"exec","risk":"high","side_effects":["Instance begins booting; machine-type billing resumes.","An ephemeral external IPv4 changes across a stop/start unless a static address is reserved."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Start a stopped VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["power on","boot VM","recover stopped instance"],"command":{"binary":"gcloud","argv":["compute","instances","start","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--async","--format=json(name,status,operationType,progress,insertTime,startTime,endTime,targetLink,zone,region,error,warnings,httpErrorStatusCode,httpErrorMessage)","--quiet"]}},{"id":"gcp.instance_stop","title":"gcloud compute instances stop","summary":"Stop one running Compute Engine instance in its zone. The guest OS is shut down and every workload on the instance goes offline until it is started again. Returns the zonal operation immediately without waiting for the shutdown; poll gcp.operation_status until it reports DONE.","description":"Stop one running Compute Engine instance in its zone. The guest OS is shut down and every workload on the instance goes offline until it is started again. Returns the zonal operation immediately without waiting for the shutdown; poll gcp.operation_status until it reports DONE.","kind":"exec","risk":"high","side_effects":["All workloads on the instance go offline; connections are dropped.","An ephemeral external IPv4 is released; a new one is assigned on start.","Machine-type billing stops; attached disks keep billing and their data."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Stop a misbehaving VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["power off","shut down VM","take instance offline"],"command":{"binary":"gcloud","argv":["compute","instances","stop","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--async","--format=json(name,status,operationType,progress,insertTime,startTime,endTime,targetLink,zone,region,error,warnings,httpErrorStatusCode,httpErrorMessage)","--quiet"]}},{"id":"gcp.mig_health","title":"gcloud compute instance-groups managed describe (health summary)","summary":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","description":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns group configuration and status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"Show a zonal MIG health summary","args":{"group":"workers","location":"us-central1-a","project":"example-prod","scope":"zone"}}],"search_terms":["managed instance group unhealthy","MIG rollout","MIG stable"]},{"id":"gcp.mig_instances","title":"gcloud compute instance-groups managed list-instances","summary":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","description":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Returned managed-instance records are capped at 500."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"List instances in a regional MIG","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region"}}],"search_terms":[]},{"id":"gcp.mig_resize","title":"gcloud compute instance-groups managed resize","summary":"Resize one zonal or regional managed instance group to an exact instance count. Scaling down deletes surplus instances; size 0 deletes every instance and the group serves nothing until scaled back up. Fails on a group managed by an autoscaler. Waits for the resize to be accepted and returns the group's new target size; instances converge asynchronously (watch with gcp.mig_health).","description":"Resize one zonal or regional managed instance group to an exact instance count. Scaling down deletes surplus instances; size 0 deletes every instance and the group serves nothing until scaled back up. Fails on a group managed by an autoscaler. Waits for the resize to be accepted and returns the group's new target size; instances converge asynchronously (watch with gcp.mig_health).","kind":"script","risk":"high","side_effects":["Scaling down DELETES surplus instances and their auto-delete disks; size 0 empties the group.","Scaling up creates instances from the group's current template; billing changes with the size.","Rejected when an autoscaler manages the group's size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"size","type":"integer","required":true,"description":"Exact target number of instances; 0 deletes every instance in the group.","validation":{"min":0,"max":1000}}],"examples":[{"title":"Scale a regional MIG to 3 instances","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region","size":3}}],"search_terms":["scale out","scale in","add capacity","drain group"]},{"id":"gcp.operation_status","title":"gcloud compute operations describe","summary":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","description":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns operation status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"operation","type":"string","required":true,"description":"Compute Engine operation name.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{0,126}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Operation scope.","validation":{"enum":["global","region","zone"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region or zone for a scoped operation; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$"}}],"examples":[{"title":"Check a zonal operation","args":{"location":"us-central1-a","operation":"operation-1712345678901-abcdef","project":"example-prod","scope":"zone"}}],"search_terms":[]}]},{"version":"0.2.0","content_hash":"sha256:8df5c0c0c759c0a491435e39bb00f91371f2711d54334a3114c097ad21c2c2b2","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-compute/0.2.0/8df5c0c0c759c0a491435e39bb00f91371f2711d54334a3114c097ad21c2c2b2/pack.tar.gz","actions":[{"id":"gcp.instance_delete","title":"gcloud compute instances delete","summary":"Permanently delete one Compute Engine instance from its zone. Cannot be undone: local SSDs are always destroyed and attached disks marked auto-delete are destroyed with it. Fails on an instance with deletion protection enabled. Waits until the deletion completes and reports the deleted instance URL on stderr.","description":"Permanently delete one Compute Engine instance from its zone. Cannot be undone: local SSDs are always destroyed and attached disks marked auto-delete are destroyed with it. Fails on an instance with deletion protection enabled. Waits until the deletion completes and reports the deleted instance URL on stderr.","kind":"exec","risk":"critical","side_effects":["Instance is shut down and DELETED; this is irreversible.","Local SSD data is always destroyed; auto-delete disks (boot disk by default) are destroyed too.","Instance IPs are released; a managed instance group may recreate a deleted member."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Delete a decommissioned VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["terminate VM","decommission instance","remove instance"],"command":{"binary":"gcloud","argv":["compute","instances","delete","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json","--quiet"]}},{"id":"gcp.instance_describe","title":"gcloud compute instances describe","summary":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","description":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Does not return instance metadata values or serial output."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Describe a production VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["compute","instances","describe","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,id,status,zone,machineType,creationTimestamp,lastStartTimestamp,lastStopTimestamp,lastSuspendedTimestamp,cpuPlatform,hostname,deletionProtection,canIpForward,networkInterfaces,disks,scheduling,serviceAccounts,tags,labels,metadata.fingerprint)","--quiet"]}},{"id":"gcp.instance_reset","title":"gcloud compute instances reset","summary":"Reset one Compute Engine instance in its zone — a hard power cycle for a hung VM. The guest OS gets no shutdown signal, so unflushed writes are lost; the instance keeps its IPs and disks. Waits for the reset to be issued and returns the instance's lifecycle state.","description":"Reset one Compute Engine instance in its zone — a hard power cycle for a hung VM. The guest OS gets no shutdown signal, so unflushed writes are lost; the instance keeps its IPs and disks. Waits for the reset to be issued and returns the instance's lifecycle state.","kind":"exec","risk":"high","side_effects":["Immediate hard reboot with no guest shutdown; in-memory and unflushed data are lost.","Connections are dropped until the instance finishes rebooting.","The instance keeps its IPs, disks, and metadata."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Power-cycle a hung VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["hard reboot","hung VM","power cycle"],"command":{"binary":"gcloud","argv":["compute","instances","reset","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,status,zone,lastStartTimestamp,lastStopTimestamp)","--quiet"]}},{"id":"gcp.instance_serial_output","title":"gcloud compute instances get-serial-port-output","summary":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","description":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns guest-written serial output and may expose data the guest logged."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"port","type":"integer","required":false,"default":1,"description":"Serial port number.","validation":{"min":1,"max":4}},{"name":"start","type":"integer","required":false,"default":0,"description":"Zero-based byte offset at which to start reading.","validation":{"min":0,"max":9007199254740991}}],"examples":[{"title":"Read the primary boot console","args":{"instance":"api-01","port":1,"project":"example-prod","start":0,"zone":"us-central1-a"}}],"search_terms":["boot failure","startup log","VM console"],"command":{"binary":"gcloud","argv":["compute","instances","get-serial-port-output","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--port={{ args.port }}","--start={{ args.start }}","--quiet"]}},{"id":"gcp.instance_start","title":"gcloud compute instances start","summary":"Start one stopped Compute Engine instance in its zone. Returns the zonal operation immediately without waiting for the boot; poll gcp.operation_status until it reports DONE.","description":"Start one stopped Compute Engine instance in its zone. Returns the zonal operation immediately without waiting for the boot; poll gcp.operation_status until it reports DONE.","kind":"exec","risk":"high","side_effects":["Instance begins booting; machine-type billing resumes.","An ephemeral external IPv4 changes across a stop/start unless a static address is reserved."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Start a stopped VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["power on","boot VM","recover stopped instance"],"command":{"binary":"gcloud","argv":["compute","instances","start","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--async","--format=json(name,status,operationType,progress,insertTime,startTime,endTime,targetLink,zone,region,error,warnings,httpErrorStatusCode,httpErrorMessage)","--quiet"]}},{"id":"gcp.instance_stop","title":"gcloud compute instances stop","summary":"Stop one running Compute Engine instance in its zone. The guest OS is shut down and every workload on the instance goes offline until it is started again. Returns the zonal operation immediately without waiting for the shutdown; poll gcp.operation_status until it reports DONE.","description":"Stop one running Compute Engine instance in its zone. The guest OS is shut down and every workload on the instance goes offline until it is started again. Returns the zonal operation immediately without waiting for the shutdown; poll gcp.operation_status until it reports DONE.","kind":"exec","risk":"high","side_effects":["All workloads on the instance go offline; connections are dropped.","An ephemeral external IPv4 is released; a new one is assigned on start.","Machine-type billing stops; attached disks keep billing and their data."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Stop a misbehaving VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":["power off","shut down VM","take instance offline"],"command":{"binary":"gcloud","argv":["compute","instances","stop","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--async","--format=json(name,status,operationType,progress,insertTime,startTime,endTime,targetLink,zone,region,error,warnings,httpErrorStatusCode,httpErrorMessage)","--quiet"]}},{"id":"gcp.mig_health","title":"gcloud compute instance-groups managed describe (health summary)","summary":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","description":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns group configuration and status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"Show a zonal MIG health summary","args":{"group":"workers","location":"us-central1-a","project":"example-prod","scope":"zone"}}],"search_terms":["managed instance group unhealthy","MIG rollout","MIG stable"]},{"id":"gcp.mig_instances","title":"gcloud compute instance-groups managed list-instances","summary":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","description":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Returned managed-instance records are capped at 500."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"List instances in a regional MIG","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region"}}],"search_terms":[]},{"id":"gcp.mig_resize","title":"gcloud compute instance-groups managed resize","summary":"Resize one zonal or regional managed instance group to an exact instance count. Scaling down deletes surplus instances; size 0 deletes every instance and the group serves nothing until scaled back up. Fails on a group managed by an autoscaler. Waits for the resize to be accepted and returns the group's new target size; instances converge asynchronously (watch with gcp.mig_health).","description":"Resize one zonal or regional managed instance group to an exact instance count. Scaling down deletes surplus instances; size 0 deletes every instance and the group serves nothing until scaled back up. Fails on a group managed by an autoscaler. Waits for the resize to be accepted and returns the group's new target size; instances converge asynchronously (watch with gcp.mig_health).","kind":"script","risk":"high","side_effects":["Scaling down DELETES surplus instances and their auto-delete disks; size 0 empties the group.","Scaling up creates instances from the group's current template; billing changes with the size.","Rejected when an autoscaler manages the group's size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"size","type":"integer","required":true,"description":"Exact target number of instances; 0 deletes every instance in the group.","validation":{"min":0,"max":1000}}],"examples":[{"title":"Scale a regional MIG to 3 instances","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region","size":3}}],"search_terms":["scale out","scale in","add capacity","drain group"]},{"id":"gcp.operation_status","title":"gcloud compute operations describe","summary":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","description":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns operation status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"operation","type":"string","required":true,"description":"Compute Engine operation name.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{0,126}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Operation scope.","validation":{"enum":["global","region","zone"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region or zone for a scoped operation; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$"}}],"examples":[{"title":"Check a zonal operation","args":{"location":"us-central1-a","operation":"operation-1712345678901-abcdef","project":"example-prod","scope":"zone"}}],"search_terms":[]}]},{"version":"0.1.1","content_hash":"sha256:456de921d2f10e2c5795b4378195022f3d8e201156f01815615def87223f144a","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-compute/0.1.1/456de921d2f10e2c5795b4378195022f3d8e201156f01815615def87223f144a/pack.tar.gz","actions":[{"id":"gcp.instance_describe","title":"gcloud compute instances describe","summary":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","description":"Show one Compute Engine instance's diagnostic configuration and lifecycle state. Metadata values are deliberately omitted because startup scripts and custom metadata can contain credentials; only the metadata fingerprint is returned.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Does not return instance metadata values or serial output."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}}],"examples":[{"title":"Describe a production VM","args":{"instance":"api-01","project":"example-prod","zone":"us-central1-a"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["compute","instances","describe","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--format=json(name,id,status,zone,machineType,creationTimestamp,lastStartTimestamp,lastStopTimestamp,lastSuspendedTimestamp,cpuPlatform,hostname,deletionProtection,canIpForward,networkInterfaces,disks,scheduling,serviceAccounts,tags,labels,metadata.fingerprint)","--quiet"]}},{"id":"gcp.instance_serial_output","title":"gcloud compute instances get-serial-port-output","summary":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","description":"Get bounded serial-port output for one Compute Engine instance. Boot logs can contain application-written sensitive data, so restrict this action by policy. Use the byte offset returned by gcloud to resume a prior read.","kind":"exec","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns guest-written serial output and may expose data the guest logged."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"zone","type":"string","required":true,"description":"Compute Engine zone.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"instance","type":"string","required":true,"description":"Instance name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"port","type":"integer","required":false,"default":1,"description":"Serial port number.","validation":{"min":1,"max":4}},{"name":"start","type":"integer","required":false,"default":0,"description":"Zero-based byte offset at which to start reading.","validation":{"min":0,"max":9007199254740991}}],"examples":[{"title":"Read the primary boot console","args":{"instance":"api-01","port":1,"project":"example-prod","start":0,"zone":"us-central1-a"}}],"search_terms":["boot failure","startup log","VM console"],"command":{"binary":"gcloud","argv":["compute","instances","get-serial-port-output","{{ args.instance }}","--project={{ args.project }}","--zone={{ args.zone }}","--port={{ args.port }}","--start={{ args.start }}","--quiet"]}},{"id":"gcp.mig_health","title":"gcloud compute instance-groups managed describe (health summary)","summary":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","description":"Show one managed instance group's target size, stability and version state, autohealing policy, update policy, and backing instance group.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns group configuration and status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"Show a zonal MIG health summary","args":{"group":"workers","location":"us-central1-a","project":"example-prod","scope":"zone"}}],"search_terms":["managed instance group unhealthy","MIG rollout","MIG stable"]},{"id":"gcp.mig_instances","title":"gcloud compute instance-groups managed list-instances","summary":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","description":"List up to 500 instances in one zonal or regional managed instance group, including lifecycle state, current action, version, and last-attempt errors.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Returned managed-instance records are capped at 500."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"group","type":"string","required":true,"description":"Managed instance group name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Whether the managed instance group is zonal or regional.","validation":{"enum":["zone","region"]}},{"name":"location","type":"string","required":true,"description":"Zone or region selected by scope.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}}],"examples":[{"title":"List instances in a regional MIG","args":{"group":"api","location":"us-central1","project":"example-prod","scope":"region"}}],"search_terms":[]},{"id":"gcp.operation_status","title":"gcloud compute operations describe","summary":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","description":"Show the status, progress, timing, target, warnings, and errors for one global, regional, or zonal Compute Engine operation.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Returns operation status only."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"operation","type":"string","required":true,"description":"Compute Engine operation name.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{0,126}[a-z0-9])?$"}},{"name":"scope","type":"string","required":true,"description":"Operation scope.","validation":{"enum":["global","region","zone"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region or zone for a scoped operation; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$"}}],"examples":[{"title":"Check a zonal operation","args":{"location":"us-central1-a","operation":"operation-1712345678901-abcdef","project":"example-prod","scope":"zone"}}],"search_terms":[]}]}]},{"id":"gcp-dns","name":"Google Cloud DNS diagnostics and record control","version":"0.2.1","description":"Cloud DNS diagnostics plus governed exact-record control: managed-zone, DNSSEC, server-policy, response-policy, and exact-record reads, and upsert or delete of one exact record set with explicit zone, name, type, TTL, and value semantics. Zone-wide record dumps and arbitrary change batches are intentionally excluded.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-dns","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-dns","content_hash":"sha256:555d2a6b0a20d70f6046c35929a66fee08a265e49f21d1f6e56d759804bf0e6a","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-dns/0.2.1/555d2a6b0a20d70f6046c35929a66fee08a265e49f21d1f6e56d759804bf0e6a/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives gcloud and projects Cloud DNS API responses locally before they leave the runner. Authenticate gcloud before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Grant least privilege for the actions you enable: reads need roles/dns.reader or equivalent; the record upsert and delete mutations need roles/dns.admin-equivalent permissions on the target zones.","Exact record and response-policy-rule actions return DNS record data, including TXT values when explicitly requested.","Projected actions use mode-0600 temporary response files and remove them before exit.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed."],"verify":"gcp.dns_zones"},"actions":[{"id":"gcp.dns_policies","title":"gcloud dns policies list","summary":"List bounded Cloud DNS server policies, networks, forwarding targets, and logging state.","description":"List bounded Cloud DNS server policies, networks, forwarding targets, and logging state.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project DNS policies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_record_delete","title":"gcloud dns record-sets delete","summary":"Delete one exact DNS record set from a managed zone after verifying that the live record data matches the expected values; refuses without mutating when the live data differs, the set is absent, or it carries a routing policy instead of plain record data.","description":"Delete one exact DNS record set from a managed zone after verifying that the live record data matches the expected values; refuses without mutating when the live data differs, the set is absent, or it carries a routing policy instead of plain record data. The deletion is applied through a DNS change that names the verified record data, so the provider rejects it — deleting nothing — if the record set changes concurrently. Returns the deleted record set — roll back by recreating it with gcp.dns_record_upsert. Resolvers keep serving cached answers until the TTL expires.","kind":"script","risk":"high","side_effects":["The record set is removed; the name stops resolving for that type as resolver caches expire.","Refused with exit 3 and no API mutation when the live record data does not exactly match the expected values.","Fails without deleting when the record set is modified between verification and the change, because the change's deletion no longer matches live data."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_*](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type. The Cloud DNS-managed SOA record cannot be deleted.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SPF","SRV","SSHFP","TLSA","TXT"]}},{"name":"values","type":"string","required":true,"description":"Expected current record data, comma-separated for multiple values, in any order. Deletion proceeds only when the live data matches exactly; read it first with gcp.dns_record_lookup. A comma always separates values, and no value may start with \"-\" or \"^\".","validation":{"pattern":"^[ -+.-\\]_-~][ -+\\--~]{0,998}(?:,[ -+.-\\]_-~][ -+\\--~]{0,998})*$","max_length":1000}}],"examples":[{"title":"Remove a retired service record after confirming its data","args":{"name":"old.example.test.","project":"example-prod","type":"A","values":"203.0.113.10","zone":"app"}}],"search_terms":["remove DNS record","delete record set","unpublish name"]},{"id":"gcp.dns_record_lookup","title":"gcloud dns record-sets list --name --type","summary":"Look up one exact DNS name and record type in a managed zone.","description":"Look up one exact DNS name and record type in a managed zone.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API call capped at 100 matching record sets.","Returns record data, including TXT values when that type is requested."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_*](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SOA","SPF","SRV","SSHFP","TLSA","TXT"]}}],"examples":[{"title":"Application address record","args":{"name":"api.example.test.","project":"example-prod","type":"A","zone":"app"}}],"search_terms":[]},{"id":"gcp.dns_record_upsert","title":"gcloud dns record-sets create or update","summary":"Create or replace one exact DNS record set in a managed zone with the given TTL and record data. Existing data for that name and type is overwritten: read it first with gcp.dns_record_lookup, and roll back by upserting the previous values. Resolvers keep serving cached answers until the previous TTL expires.","description":"Create or replace one exact DNS record set in a managed zone with the given TTL and record data. Existing data for that name and type is overwritten: read it first with gcp.dns_record_lookup, and roll back by upserting the previous values. Resolvers keep serving cached answers until the previous TTL expires.","kind":"script","risk":"high","side_effects":["Creates the record set when absent; otherwise replaces its TTL and record data.","Replaces any routing policy on the record set with the given static data.","Resolvers serve the previous data until its TTL expires."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_*](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type. The Cloud DNS-managed SOA record cannot be upserted.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SPF","SRV","SSHFP","TLSA","TXT"]}},{"name":"ttl","type":"integer","required":true,"description":"Record TTL in seconds.","validation":{"min":1,"max":604800}},{"name":"values","type":"string","required":true,"description":"Complete record data for the set, comma-separated for multiple values (for example two A addresses). A comma always separates values — a literal comma inside one value is not supported — and no value may start with \"-\" or \"^\".","validation":{"pattern":"^[ -+.-\\]_-~][ -+\\--~]{0,998}(?:,[ -+.-\\]_-~][ -+\\--~]{0,998})*$","max_length":1000}}],"examples":[{"title":"Point an application address record at a healthy IP","args":{"name":"api.example.test.","project":"example-prod","ttl":300,"type":"A","values":"203.0.113.40","zone":"app"}}],"search_terms":["set DNS record","update A record","point hostname","DNS failover"]},{"id":"gcp.dns_response_policies","title":"gcloud dns response-policies list","summary":"List bounded Cloud DNS response policies and attached networks or GKE clusters.","description":"List bounded Cloud DNS response policies and attached networks or GKE clusters.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Cloud DNS response-policy service location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum response policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global response policies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_response_policy_rules","title":"gcloud dns response-policies rules list","summary":"List bounded DNS names, behavior, and local record data in one response policy.","description":"List bounded DNS names, behavior, and local record data in one response policy.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Returns local record data, including TXT values.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"response_policy","type":"string","required":true,"description":"Response-policy name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Cloud DNS response-policy service location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application response-policy rules","args":{"project":"example-prod","response_policy":"app"}}],"search_terms":[]},{"id":"gcp.dns_zone_describe","title":"gcloud dns managed-zones describe","summary":"Show one managed zone's visibility, DNSSEC, nameservers, and forwarding or peering topology.","description":"Show one managed zone's visibility, DNSSEC, nameservers, and forwarding or peering topology.","kind":"script","risk":"low","side_effects":["One read-only Cloud DNS API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Application DNS zone","args":{"project":"example-prod","zone":"app"}}],"search_terms":[]},{"id":"gcp.dns_zones","title":"gcloud dns managed-zones list","summary":"List bounded managed-zone visibility, DNSSEC, nameservers, and forwarding or peering topology.","description":"List bounded managed-zone visibility, DNSSEC, nameservers, and forwarding or peering topology.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum zones to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project managed zones","args":{"project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.2.0","content_hash":"sha256:4163dda5066fe4553d38a94d9b1f8eca62595cf7246ee3ef7900de57251ad99b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-dns/0.2.0/4163dda5066fe4553d38a94d9b1f8eca62595cf7246ee3ef7900de57251ad99b/pack.tar.gz","actions":[{"id":"gcp.dns_policies","title":"gcloud dns policies list","summary":"List bounded Cloud DNS server policies, networks, forwarding targets, and logging state.","description":"List bounded Cloud DNS server policies, networks, forwarding targets, and logging state.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project DNS policies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_record_delete","title":"gcloud dns record-sets delete","summary":"Delete one exact DNS record set from a managed zone after verifying that the live record data matches the expected values; refuses without mutating when the live data differs, the set is absent, or it carries a routing policy instead of plain record data.","description":"Delete one exact DNS record set from a managed zone after verifying that the live record data matches the expected values; refuses without mutating when the live data differs, the set is absent, or it carries a routing policy instead of plain record data. The deletion is applied through a DNS change that names the verified record data, so the provider rejects it — deleting nothing — if the record set changes concurrently. Returns the deleted record set — roll back by recreating it with gcp.dns_record_upsert. Resolvers keep serving cached answers until the TTL expires.","kind":"script","risk":"high","side_effects":["The record set is removed; the name stops resolving for that type as resolver caches expire.","Refused with exit 3 and no API mutation when the live record data does not exactly match the expected values.","Fails without deleting when the record set is modified between verification and the change, because the change's deletion no longer matches live data."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_*](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type. The Cloud DNS-managed SOA record cannot be deleted.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SPF","SRV","SSHFP","TLSA","TXT"]}},{"name":"values","type":"string","required":true,"description":"Expected current record data, comma-separated for multiple values, in any order. Deletion proceeds only when the live data matches exactly; read it first with gcp.dns_record_lookup. A comma always separates values, and no value may start with \"-\" or \"^\".","validation":{"pattern":"^[ -+.-\\]_-~][ -+\\--~]{0,998}(?:,[ -+.-\\]_-~][ -+\\--~]{0,998})*$","max_length":1000}}],"examples":[{"title":"Remove a retired service record after confirming its data","args":{"name":"old.example.test.","project":"example-prod","type":"A","values":"203.0.113.10","zone":"app"}}],"search_terms":["remove DNS record","delete record set","unpublish name"]},{"id":"gcp.dns_record_lookup","title":"gcloud dns record-sets list --name --type","summary":"Look up one exact DNS name and record type in a managed zone.","description":"Look up one exact DNS name and record type in a managed zone.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API call capped at 100 matching record sets.","Returns record data, including TXT values when that type is requested."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_*](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SOA","SPF","SRV","SSHFP","TLSA","TXT"]}}],"examples":[{"title":"Application address record","args":{"name":"api.example.test.","project":"example-prod","type":"A","zone":"app"}}],"search_terms":[]},{"id":"gcp.dns_record_upsert","title":"gcloud dns record-sets create or update","summary":"Create or replace one exact DNS record set in a managed zone with the given TTL and record data. Existing data for that name and type is overwritten: read it first with gcp.dns_record_lookup, and roll back by upserting the previous values. Resolvers keep serving cached answers until the previous TTL expires.","description":"Create or replace one exact DNS record set in a managed zone with the given TTL and record data. Existing data for that name and type is overwritten: read it first with gcp.dns_record_lookup, and roll back by upserting the previous values. Resolvers keep serving cached answers until the previous TTL expires.","kind":"script","risk":"high","side_effects":["Creates the record set when absent; otherwise replaces its TTL and record data.","Replaces any routing policy on the record set with the given static data.","Resolvers serve the previous data until its TTL expires."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_*](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type. The Cloud DNS-managed SOA record cannot be upserted.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SPF","SRV","SSHFP","TLSA","TXT"]}},{"name":"ttl","type":"integer","required":true,"description":"Record TTL in seconds.","validation":{"min":1,"max":604800}},{"name":"values","type":"string","required":true,"description":"Complete record data for the set, comma-separated for multiple values (for example two A addresses). A comma always separates values — a literal comma inside one value is not supported — and no value may start with \"-\" or \"^\".","validation":{"pattern":"^[ -+.-\\]_-~][ -+\\--~]{0,998}(?:,[ -+.-\\]_-~][ -+\\--~]{0,998})*$","max_length":1000}}],"examples":[{"title":"Point an application address record at a healthy IP","args":{"name":"api.example.test.","project":"example-prod","ttl":300,"type":"A","values":"203.0.113.40","zone":"app"}}],"search_terms":["set DNS record","update A record","point hostname","DNS failover"]},{"id":"gcp.dns_response_policies","title":"gcloud dns response-policies list","summary":"List bounded Cloud DNS response policies and attached networks or GKE clusters.","description":"List bounded Cloud DNS response policies and attached networks or GKE clusters.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Cloud DNS response-policy service location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum response policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global response policies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_response_policy_rules","title":"gcloud dns response-policies rules list","summary":"List bounded DNS names, behavior, and local record data in one response policy.","description":"List bounded DNS names, behavior, and local record data in one response policy.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Returns local record data, including TXT values.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"response_policy","type":"string","required":true,"description":"Response-policy name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Cloud DNS response-policy service location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application response-policy rules","args":{"project":"example-prod","response_policy":"app"}}],"search_terms":[]},{"id":"gcp.dns_zone_describe","title":"gcloud dns managed-zones describe","summary":"Show one managed zone's visibility, DNSSEC, nameservers, and forwarding or peering topology.","description":"Show one managed zone's visibility, DNSSEC, nameservers, and forwarding or peering topology.","kind":"script","risk":"low","side_effects":["One read-only Cloud DNS API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Application DNS zone","args":{"project":"example-prod","zone":"app"}}],"search_terms":[]},{"id":"gcp.dns_zones","title":"gcloud dns managed-zones list","summary":"List bounded managed-zone visibility, DNSSEC, nameservers, and forwarding or peering topology.","description":"List bounded managed-zone visibility, DNSSEC, nameservers, and forwarding or peering topology.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum zones to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project managed zones","args":{"project":"example-prod"}}],"search_terms":[]}]},{"version":"0.1.0","content_hash":"sha256:570965ac547b3b368d108e4e5f2b0baaa12a170b2bf393a770542e7113027600","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-dns/0.1.0/570965ac547b3b368d108e4e5f2b0baaa12a170b2bf393a770542e7113027600/pack.tar.gz","actions":[{"id":"gcp.dns_policies","title":"gcloud dns policies list","summary":"List bounded Cloud DNS server policies, networks, forwarding targets, and logging state.","description":"List bounded Cloud DNS server policies, networks, forwarding targets, and logging state.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project DNS policies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_record_lookup","title":"gcloud dns record-sets list --name --type","summary":"Look up one exact DNS name and record type in a managed zone.","description":"Look up one exact DNS name and record type in a managed zone.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API call capped at 100 matching record sets.","Returns record data, including TXT values when that type is requested."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"name","type":"string","required":true,"description":"Fully qualified DNS name ending with a dot.","validation":{"pattern":"^[A-Za-z0-9_.*-](?:[A-Za-z0-9_.*-]{0,251}[A-Za-z0-9_*-])?\\.$","max_length":253}},{"name":"type","type":"string","required":true,"description":"DNS record type.","validation":{"enum":["A","AAAA","CAA","CNAME","DS","IPSECKEY","MX","NAPTR","NS","PTR","SOA","SPF","SRV","SSHFP","TLSA","TXT"]}}],"examples":[{"title":"Application address record","args":{"name":"api.example.test.","project":"example-prod","type":"A","zone":"app"}}],"search_terms":[]},{"id":"gcp.dns_response_policies","title":"gcloud dns response-policies list","summary":"List bounded Cloud DNS response policies and attached networks or GKE clusters.","description":"List bounded Cloud DNS response policies and attached networks or GKE clusters.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"location","type":"string","required":false,"default":"global","description":"Cloud DNS response-policy service location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum response policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Global response policies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.dns_response_policy_rules","title":"gcloud dns response-policies rules list","summary":"List bounded DNS names, behavior, and local record data in one response policy.","description":"List bounded DNS names, behavior, and local record data in one response policy.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Returns local record data, including TXT values.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"response_policy","type":"string","required":true,"description":"Response-policy name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"location","type":"string","required":false,"default":"global","description":"Cloud DNS response-policy service location.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application response-policy rules","args":{"project":"example-prod","response_policy":"app"}}],"search_terms":[]},{"id":"gcp.dns_zone_describe","title":"gcloud dns managed-zones describe","summary":"Show one managed zone's visibility, DNSSEC, nameservers, and forwarding or peering topology.","description":"Show one managed zone's visibility, DNSSEC, nameservers, and forwarding or peering topology.","kind":"script","risk":"low","side_effects":["One read-only Cloud DNS API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"zone","type":"string","required":true,"description":"Managed-zone name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Application DNS zone","args":{"project":"example-prod","zone":"app"}}],"search_terms":[]},{"id":"gcp.dns_zones","title":"gcloud dns managed-zones list","summary":"List bounded managed-zone visibility, DNSSEC, nameservers, and forwarding or peering topology.","description":"List bounded managed-zone visibility, DNSSEC, nameservers, and forwarding or peering topology.","kind":"script","risk":"low","side_effects":["Read-only Cloud DNS API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum zones to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project managed zones","args":{"project":"example-prod"}}],"search_terms":[]}]}]},{"id":"gcp-iam","name":"Google Cloud IAM diagnostics","version":"0.1.2","description":"Read-only Google Cloud IAM diagnostics for workload identity providers, workload identity pools, and service-account policies. Every action names the target project and global location explicitly.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-iam","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-iam","content_hash":"sha256:04ed06db4c593ec030777ac67fc0923147e13c43eff00f1f462c70418a16baf9","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-iam/0.1.2/04ed06db4c593ec030777ac67fc0923147e13c43eff00f1f462c70418a16baf9/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the gcloud CLI on the runner host. Authenticate gcloud with a workload identity, attached service account, service-account credential, or operator configuration before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional path to a credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Any credential/config env you set must be allowlisted in the runner's `execution.inherit_env`; attached service accounts and workload identity need no credential env.","For a credential file, populate a dedicated `CLOUDSDK_CONFIG` with `gcloud auth login --cred-file=...` or set `CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE`; ordinary gcloud commands do not authenticate from GOOGLE_APPLICATION_CREDENTIALS.","Use a read-only principal. Workload identity reads need roles/iam.workloadIdentityPoolViewer; service-account policy reads need roles/iam.serviceAccountViewer or equivalent permissions.","This is a remote-target client pack and is never host-auto-suggested merely because gcloud is installed.","All actions pass --quiet and an explicit --project, so ambient project configuration cannot redirect a request."],"verify":"gcp.workload_identity_pools"},"actions":[{"id":"gcp.service_account_policy","title":"gcloud iam service-accounts get-iam-policy","summary":"Show the IAM policy attached to one service account, including bindings, members, conditions, etag, and policy version.","description":"Show the IAM policy attached to one service account, including bindings, members, conditions, etag, and policy version.","kind":"exec","risk":"low","side_effects":["One read-only IAM API call.","Returns principal identities present in the policy."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"service_account","type":"string","required":true,"description":"Full service-account email address.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]@[a-z][a-z0-9-]{4,28}[a-z0-9]\\.iam\\.gserviceaccount\\.com$"}}],"examples":[{"title":"Service-account bindings","args":{"project":"example-prod","service_account":"deployer@example-prod.iam.gserviceaccount.com"}}],"search_terms":["service account impersonation","workloadIdentityUser"],"command":{"binary":"gcloud","argv":["iam","service-accounts","get-iam-policy","{{ args.service_account }}","--project={{ args.project }}","--format=json","--quiet"]}},{"id":"gcp.wif_provider_describe","title":"gcloud iam workload-identity-pools providers describe","summary":"Describe one global workload identity pool provider, including its issuer, attribute mapping, attribute condition, and enabled or disabled state.","description":"Describe one global workload identity pool provider, including its issuer, attribute mapping, attribute condition, and enabled or disabled state.","kind":"exec","risk":"low","side_effects":["One read-only IAM API call.","Returns provider configuration but no credential material."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"pool_id","type":"string","required":true,"description":"Workload identity pool ID.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{2,30}[a-z0-9])$"}},{"name":"provider_id","type":"string","required":true,"description":"Workload identity provider ID.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{2,30}[a-z0-9])$"}}],"examples":[{"title":"Describe a GitHub OIDC provider","args":{"pool_id":"automation-pool","project":"example-prod","provider_id":"github-actions"}}],"search_terms":["Workload Identity Federation","WIF provider","OIDC issuer"],"command":{"binary":"gcloud","argv":["iam","workload-identity-pools","providers","describe","{{ args.provider_id }}","--workload-identity-pool={{ args.pool_id }}","--location=global","--project={{ args.project }}","--format=json","--quiet"]}},{"id":"gcp.workload_identity_pools","title":"gcloud iam workload-identity-pools list","summary":"List global workload identity pools in one project, including state, descriptions, and resource names.","description":"List global workload identity pools in one project, including state, descriptions, and resource names.","kind":"exec","risk":"low","side_effects":["One read-only IAM API call.","Returned pools are capped by limit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum pools to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project workload identity pools","args":{"limit":100,"project":"example-prod"}}],"search_terms":["Workload Identity Federation","WIF pools"],"command":{"binary":"gcloud","argv":["iam","workload-identity-pools","list","--location=global","--project={{ args.project }}","--limit={{ args.limit }}","--format=json","--quiet"]}}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:c8bc2db792a56ae123ea865287e029a0ecf6e95e5790722dcae3ff01449d480b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-iam/0.1.0/c8bc2db792a56ae123ea865287e029a0ecf6e95e5790722dcae3ff01449d480b/pack.tar.gz","actions":[{"id":"gcp.service_account_policy","title":"gcloud iam service-accounts get-iam-policy","summary":"Show the IAM policy attached to one service account, including bindings, members, conditions, etag, and policy version.","description":"Show the IAM policy attached to one service account, including bindings, members, conditions, etag, and policy version.","kind":"exec","risk":"low","side_effects":["One read-only IAM API call.","Returns principal identities present in the policy."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"service_account","type":"string","required":true,"description":"Full service-account email address.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]@[a-z][a-z0-9-]{4,28}[a-z0-9]\\.iam\\.gserviceaccount\\.com$"}}],"examples":[{"title":"Service-account bindings","args":{"project":"example-prod","service_account":"deployer@example-prod.iam.gserviceaccount.com"}}],"search_terms":["service account impersonation","workloadIdentityUser"],"command":{"binary":"gcloud","argv":["iam","service-accounts","get-iam-policy","{{ args.service_account }}","--project={{ args.project }}","--format=json","--quiet"]}},{"id":"gcp.wif_provider_describe","title":"gcloud iam workload-identity-pools providers describe","summary":"Describe one global workload identity pool provider, including its issuer, attribute mapping, attribute condition, and enabled or disabled state.","description":"Describe one global workload identity pool provider, including its issuer, attribute mapping, attribute condition, and enabled or disabled state.","kind":"exec","risk":"low","side_effects":["One read-only IAM API call.","Returns provider configuration but no credential material."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"pool_id","type":"string","required":true,"description":"Workload identity pool ID.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{2,30}[a-z0-9])$"}},{"name":"provider_id","type":"string","required":true,"description":"Workload identity provider ID.","validation":{"pattern":"^[a-z0-9](?:[a-z0-9-]{2,30}[a-z0-9])$"}}],"examples":[{"title":"Describe a GitHub OIDC provider","args":{"pool_id":"automation-pool","project":"example-prod","provider_id":"github-actions"}}],"search_terms":["Workload Identity Federation","WIF provider","OIDC issuer"],"command":{"binary":"gcloud","argv":["iam","workload-identity-pools","providers","describe","{{ args.provider_id }}","--workload-identity-pool={{ args.pool_id }}","--location=global","--project={{ args.project }}","--format=json","--quiet"]}},{"id":"gcp.workload_identity_pools","title":"gcloud iam workload-identity-pools list","summary":"List global workload identity pools in one project, including state, descriptions, and resource names.","description":"List global workload identity pools in one project, including state, descriptions, and resource names.","kind":"exec","risk":"low","side_effects":["One read-only IAM API call.","Returned pools are capped by limit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum pools to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project workload identity pools","args":{"limit":100,"project":"example-prod"}}],"search_terms":["Workload Identity Federation","WIF pools"],"command":{"binary":"gcloud","argv":["iam","workload-identity-pools","list","--location=global","--project={{ args.project }}","--limit={{ args.limit }}","--format=json","--quiet"]}}]}]},{"id":"gcp-load-balancing","name":"Google Cloud load-balancing diagnostics","version":"0.1.2","description":"Read-only Google Cloud load-balancer topology and health diagnostics for backend services, health checks, URL maps, target proxies, forwarding rules, and network endpoint groups. Fixed projections exclude IAP secrets, AWS-auth keys, and custom header values.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-load-balancing","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-load-balancing","content_hash":"sha256:3664aef16b4458c861383c56d7a389a8390a5a6454a0c7433e666c280b1ac04b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-load-balancing/0.1.2/3664aef16b4458c861383c56d7a389a8390a5a6454a0c7433e666c280b1ac04b/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives gcloud and locally projects API responses with jq before they leave the runner. Authenticate gcloud before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["The principal needs roles/compute.networkViewer or equivalent get/list permissions.","Complex resource projections use mode-0600 temporary files so gcloud failures remain distinguishable from jq failures; files are removed before exit.","Any credential/config env must be allowlisted in the runner's `execution.inherit_env`; attached service accounts and workload identity need no credential env.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed."],"verify":"gcp.backend_services"},"actions":[{"id":"gcp.backend_health","title":"gcloud compute backend-services get-health","summary":"Show endpoint health for one global or regional backend service.","description":"Show endpoint health for one global or regional backend service.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"backend_service","type":"string","required":true,"description":"Backend service name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"scope","type":"string","required":true,"description":"Backend service scope.","validation":{"enum":["global","region"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region for region scope; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$","max_length":63}}],"examples":[{"title":"Global application backend health","args":{"backend_service":"app","project":"example-prod","scope":"global"}}],"search_terms":[]},{"id":"gcp.backend_service_describe","title":"gcloud compute backend-services describe","summary":"Show one backend service without IAP secrets, AWS-auth keys, or header values.","description":"Show one backend service without IAP secrets, AWS-auth keys, or header values.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"backend_service","type":"string","required":true,"description":"Backend service name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"scope","type":"string","required":true,"description":"Backend service scope.","validation":{"enum":["global","region"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region for region scope; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$","max_length":63}}],"examples":[{"title":"Global application backend","args":{"backend_service":"app","project":"example-prod","scope":"global"}}],"search_terms":[]},{"id":"gcp.backend_services","title":"gcloud compute backend-services list","summary":"List bounded backend-service topology without IAP secrets, AWS-auth keys, or header values.","description":"List bounded backend-service topology without IAP secrets, AWS-auth keys, or header values.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum backend services to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project backend services","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.forwarding_rules","title":"gcloud compute forwarding-rules list","summary":"List bounded forwarding rules, addresses, ports, targets, and load-balancing scheme.","description":"List bounded forwarding rules, addresses, ports, targets, and load-balancing scheme.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum forwarding rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project forwarding rules","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.health_checks","title":"gcloud compute health-checks list","summary":"List bounded health-check probes, timing, thresholds, and logging state.","description":"List bounded health-check probes, timing, thresholds, and logging state.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum health checks to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project health checks","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.http_proxies","title":"gcloud compute target-http-proxies list","summary":"List bounded HTTP target proxies and their URL maps.","description":"List bounded HTTP target proxies and their URL maps.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum HTTP proxies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project HTTP proxies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.https_proxies","title":"gcloud compute target-https-proxies list","summary":"List bounded HTTPS target proxies, URL maps, certificates, and TLS policy.","description":"List bounded HTTPS target proxies, URL maps, certificates, and TLS policy.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum HTTPS proxies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project HTTPS proxies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.network_endpoint_groups","title":"gcloud compute network-endpoint-groups list","summary":"List bounded zonal, regional, global, and serverless network endpoint groups.","description":"List bounded zonal, regional, global, and serverless network endpoint groups.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum endpoint groups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project endpoint groups","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.url_maps","title":"gcloud compute url-maps list","summary":"List bounded host and path routing topology without custom header values.","description":"List bounded host and path routing topology without custom header values.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum URL maps to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project URL maps","args":{"project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:d43b24b0767cb62752eb368314fec257755880f6ea860c453a76bf8c3ca5820b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-load-balancing/0.1.0/d43b24b0767cb62752eb368314fec257755880f6ea860c453a76bf8c3ca5820b/pack.tar.gz","actions":[{"id":"gcp.backend_health","title":"gcloud compute backend-services get-health","summary":"Show endpoint health for one global or regional backend service.","description":"Show endpoint health for one global or regional backend service.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"backend_service","type":"string","required":true,"description":"Backend service name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"scope","type":"string","required":true,"description":"Backend service scope.","validation":{"enum":["global","region"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region for region scope; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$","max_length":63}}],"examples":[{"title":"Global application backend health","args":{"backend_service":"app","project":"example-prod","scope":"global"}}],"search_terms":[]},{"id":"gcp.backend_service_describe","title":"gcloud compute backend-services describe","summary":"Show one backend service without IAP secrets, AWS-auth keys, or header values.","description":"Show one backend service without IAP secrets, AWS-auth keys, or header values.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"backend_service","type":"string","required":true,"description":"Backend service name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"scope","type":"string","required":true,"description":"Backend service scope.","validation":{"enum":["global","region"]}},{"name":"location","type":"string","required":false,"default":"","description":"Region for region scope; empty for global.","validation":{"pattern":"^([a-z0-9][a-z0-9-]{0,62})?$","max_length":63}}],"examples":[{"title":"Global application backend","args":{"backend_service":"app","project":"example-prod","scope":"global"}}],"search_terms":[]},{"id":"gcp.backend_services","title":"gcloud compute backend-services list","summary":"List bounded backend-service topology without IAP secrets, AWS-auth keys, or header values.","description":"List bounded backend-service topology without IAP secrets, AWS-auth keys, or header values.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum backend services to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project backend services","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.forwarding_rules","title":"gcloud compute forwarding-rules list","summary":"List bounded forwarding rules, addresses, ports, targets, and load-balancing scheme.","description":"List bounded forwarding rules, addresses, ports, targets, and load-balancing scheme.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum forwarding rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project forwarding rules","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.health_checks","title":"gcloud compute health-checks list","summary":"List bounded health-check probes, timing, thresholds, and logging state.","description":"List bounded health-check probes, timing, thresholds, and logging state.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum health checks to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project health checks","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.http_proxies","title":"gcloud compute target-http-proxies list","summary":"List bounded HTTP target proxies and their URL maps.","description":"List bounded HTTP target proxies and their URL maps.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum HTTP proxies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project HTTP proxies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.https_proxies","title":"gcloud compute target-https-proxies list","summary":"List bounded HTTPS target proxies, URL maps, certificates, and TLS policy.","description":"List bounded HTTPS target proxies, URL maps, certificates, and TLS policy.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum HTTPS proxies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project HTTPS proxies","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.network_endpoint_groups","title":"gcloud compute network-endpoint-groups list","summary":"List bounded zonal, regional, global, and serverless network endpoint groups.","description":"List bounded zonal, regional, global, and serverless network endpoint groups.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum endpoint groups to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project endpoint groups","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.url_maps","title":"gcloud compute url-maps list","summary":"List bounded host and path routing topology without custom header values.","description":"List bounded host and path routing topology without custom header values.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum URL maps to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project URL maps","args":{"project":"example-prod"}}],"search_terms":[]}]}]},{"id":"gcp-monitoring","name":"Google Cloud Logging and Monitoring operations","version":"0.3.3","description":"Google Cloud Logging and Monitoring diagnostics plus governed alert control: bounded log discovery and queries, metric queries, metric descriptors, Cloud Interconnect attachment utilization, and alert-policy reads, and enable or disable of one exact alert policy. Logging and metric reads plus the alert-policy mutations use stable Google Cloud REST APIs — the mutations patch only the policy's enabled field; the alert-policy list uses the GA gcloud command.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-monitoring","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-monitoring","content_hash":"sha256:aabbc78fc3359fa47e4e358b1a52277d02dadb458d0810801587ec8e8d96fea3","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-monitoring/0.3.3/aabbc78fc3359fa47e4e358b1a52277d02dadb458d0810801587ec8e8d96fea3/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","curl","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Uses gcloud authentication on the runner host. The Logging, metric, and alert-policy REST actions obtain a short-lived access token from gcloud and send it only to fixed Google Cloud API endpoints without placing it in argv or output.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional path to a credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Any credential/config env you set must be allowlisted in the runner's `execution.inherit_env`; attached service accounts and workload identity need no credential env.","Grant least privilege for the actions you enable: ordinary Logging reads need roles/logging.viewer; private and Data Access logs additionally need roles/logging.privateLogViewer. Monitoring reads need roles/monitoring.viewer, and alert-policy enable or disable needs roles/monitoring.alertPolicyEditor-equivalent permissions. User or quota-project credentials may also need serviceusage.services.use on the named project for the X-Goog-User-Project quota header.","For a credential file, populate a dedicated `CLOUDSDK_CONFIG` with `gcloud auth login --cred-file=...` or set `CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE`; ordinary gcloud commands do not authenticate from GOOGLE_APPLICATION_CREDENTIALS.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed.","Metric query pageSize with view=FULL caps returned points rather than the number of time-series objects; follow next_page_cursor for another page."],"verify":"gcp.alert_policies"},"actions":[{"id":"gcp.alert_policies","title":"gcloud monitoring policies list","summary":"List alerting policies in one Google Cloud project.","description":"List alerting policies in one Google Cloud project.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Monitoring API pagination.","Returned policies are capped by limit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project alert policies","args":{"limit":100,"project":"example-prod"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["monitoring","policies","list","--project={{ args.project }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.alert_policy_disable","title":"Disable a Cloud Monitoring alert policy","summary":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","description":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy stops alerting; its notification channels stay silent until re-enabled."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Silence a flapping alert policy during an incident","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["disable alert","silence policy","stop alerting"]},{"id":"gcp.alert_policy_enable","title":"Enable a Cloud Monitoring alert policy","summary":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","description":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy's conditions resume evaluating and can page its notification channels."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Re-enable a CPU alert policy after maintenance","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["enable alert","resume alerting","unsilence policy"]},{"id":"gcp.interconnect_utilization","title":"Query Cloud Interconnect attachment utilization","summary":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","description":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","kind":"script","risk":"low","side_effects":["One gcloud token read and three read-only Monitoring API requests.","Writes public metric responses to mode-0600 temporary files and removes them before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"attachment","type":"string","required":true,"description":"Cloud Interconnect attachment name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"region","type":"string","required":true,"description":"Attachment region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":5,"max":360}}],"examples":[{"title":"Last hour for a VLAN attachment","args":{"attachment":"va1-primary","project":"example-prod","region":"us-central1","window_minutes":60}}],"search_terms":["Interconnect saturation","VLAN attachment utilization"]},{"id":"gcp.log_entries","title":"Query recent Cloud Logging entries","summary":"Query the newest five recent Cloud Logging entries in a Google Cloud project, optionally narrowed by minimum severity, resource type, and exact log ID. Returns fixed, clipped diagnostic fields; log content is arbitrary application output, so redaction is best-effort and the result should be treated as sensitive diagnostics.","description":"Query the newest five recent Cloud Logging entries in a Google Cloud project, optionally narrowed by minimum severity, resource type, and exact log ID. Returns fixed, clipped diagnostic fields; log content is arbitrary application output, so redaction is best-effort and the result should be treated as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One gcloud token read and one read-only Cloud Logging API request.","Returns application-controlled log content into the governed run result and audit trail."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"minimum_severity","type":"string","required":false,"default":"DEFAULT","description":"Minimum normalized Cloud Logging severity to return.","validation":{"enum":["DEFAULT","DEBUG","INFO","NOTICE","WARNING","ERROR","CRITICAL","ALERT","EMERGENCY"]}},{"name":"resource_type","type":"string","required":false,"default":"","description":"Optional exact monitored-resource type, such as gce_instance or cloud_run_revision.","validation":{"pattern":"^([a-z][a-z0-9_]{0,127})?$","max_length":128}},{"name":"log_id","type":"string","required":false,"default":"","description":"Optional exact URL-encoded log ID, without the projects/PROJECT/logs/ prefix.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9._~%+/-]{0,511})?$","max_length":512}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"page_size","type":"integer","required":false,"default":5,"description":"Maximum entries to return.","validation":{"min":1,"max":5}}],"examples":[{"title":"Recent VM errors","args":{"minimum_severity":"ERROR","page_size":5,"project":"example-prod","resource_type":"gce_instance","window_minutes":60}}],"search_terms":["query gcp logs","find cloud logging errors","recent google cloud logs"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"entries":{"items":{"additionalProperties":false,"properties":{"log_name":{"maxLength":160,"type":"string"},"message":{"maxLength":200,"type":"string"},"message_truncated":{"type":"boolean"},"resource_type":{"maxLength":64,"type":"string"},"severity":{"maxLength":16,"type":"string"},"timestamp":{"maxLength":40,"type":"string"}},"required":["timestamp","severity","resource_type","log_name","message","message_truncated"],"type":"object"},"maxItems":5,"type":"array"},"more_available":{"type":"boolean"}},"required":["entries","more_available"],"type":"object"}},{"id":"gcp.log_names","title":"List Cloud Logging log names","summary":"List one bounded page of log names that contain entries in a Google Cloud project. Use the returned continuation cursor to inspect the next page.","description":"List one bounded page of log names that contain entries in a Google Cloud project. Use the returned continuation cursor to inspect the next page.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Cloud Logging API request.","Returns names only; no log entries or payloads are read."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"page_size","type":"integer","required":false,"default":8,"description":"Maximum log names in this page.","validation":{"min":1,"max":8}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation cursor from the previous result. Provider cursors containing unsupported characters or exceeding 1,024 bytes are omitted from output and cannot be continued through this action.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":1024}}],"examples":[{"title":"First page of project logs","args":{"page_size":8,"project":"example-prod"}}],"search_terms":["list gcp logs","discover cloud logging logs"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cursor_omitted":{"type":"boolean"},"log_names":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":240,"type":"string"},"truncated":{"type":"boolean"}},"required":["name","truncated"],"type":"object"},"maxItems":8,"type":"array"},"next_page_cursor":{"maxLength":1024,"type":["string","null"]}},"required":["log_names","next_page_cursor","cursor_omitted"],"type":"object"}},{"id":"gcp.metric_descriptors","title":"List Cloud Monitoring metric descriptors","summary":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a next_page_cursor when another page exists.","description":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a next_page_cursor when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","Result count is bounded by page_size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"type_prefix","type":"string","required":false,"default":"","description":"Optional metric-type prefix.","validation":{"pattern":"^([A-Za-z][A-Za-z0-9._/-]{0,255})?$"}},{"name":"active_only","type":"boolean","required":false,"default":true,"description":"Exclude descriptors with no recent data."},{"name":"page_size","type":"integer","required":false,"default":100,"description":"Maximum descriptors in this page.","validation":{"min":1,"max":500}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Interconnect metric descriptors","args":{"active_only":true,"project":"example-prod","type_prefix":"interconnect.googleapis.com/"}}],"search_terms":[]},{"id":"gcp.metric_query","title":"Query Cloud Monitoring time series","summary":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a next_page_cursor when another page exists.","description":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a next_page_cursor when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","page_size caps returned points because the request uses view=FULL."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"metric_type","type":"string","required":true,"description":"Full metric type, such as compute.googleapis.com/instance/cpu/utilization.","validation":{"pattern":"^[A-Za-z](?:[A-Za-z0-9._/-]{0,510}[A-Za-z0-9])?$"}},{"name":"resource_filter","type":"string","required":false,"default":"","description":"Optional Monitoring filter expression appended to the fixed metric.type predicate.","validation":{"pattern":"^[ -~]*$","max_length":1024}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"alignment_seconds","type":"integer","required":false,"default":60,"description":"Alignment period when aligner is not ALIGN_NONE.","validation":{"min":60,"max":3600}},{"name":"aligner","type":"string","required":false,"default":"ALIGN_NONE","description":"Optional per-series aligner.","validation":{"enum":["ALIGN_NONE","ALIGN_DELTA","ALIGN_RATE","ALIGN_MEAN","ALIGN_MAX","ALIGN_MIN","ALIGN_SUM","ALIGN_NEXT_OLDER"]}},{"name":"page_size","type":"integer","required":false,"default":500,"description":"Maximum number of FULL-view points in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"VM CPU for one instance","args":{"aligner":"ALIGN_MEAN","alignment_seconds":300,"metric_type":"compute.googleapis.com/instance/cpu/utilization","project":"example-prod","resource_filter":"resource.type = \"gce_instance\" AND resource.labels.instance_id = \"1234567890\"","window_minutes":60}}],"search_terms":[]}],"previous_versions":[{"version":"0.3.2","content_hash":"sha256:2786ddb92d71e4747eb676b4f47b79e5153ed4ffa16429e5b98f07e8e97e86dd","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-monitoring/0.3.2/2786ddb92d71e4747eb676b4f47b79e5153ed4ffa16429e5b98f07e8e97e86dd/pack.tar.gz","actions":[{"id":"gcp.alert_policies","title":"gcloud monitoring policies list","summary":"List alerting policies in one Google Cloud project.","description":"List alerting policies in one Google Cloud project.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Monitoring API pagination.","Returned policies are capped by limit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project alert policies","args":{"limit":100,"project":"example-prod"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["monitoring","policies","list","--project={{ args.project }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.alert_policy_disable","title":"Disable a Cloud Monitoring alert policy","summary":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","description":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy stops alerting; its notification channels stay silent until re-enabled."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Silence a flapping alert policy during an incident","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["disable alert","silence policy","stop alerting"]},{"id":"gcp.alert_policy_enable","title":"Enable a Cloud Monitoring alert policy","summary":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","description":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy's conditions resume evaluating and can page its notification channels."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Re-enable a CPU alert policy after maintenance","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["enable alert","resume alerting","unsilence policy"]},{"id":"gcp.interconnect_utilization","title":"Query Cloud Interconnect attachment utilization","summary":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","description":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","kind":"script","risk":"low","side_effects":["One gcloud token read and three read-only Monitoring API requests.","Writes public metric responses to mode-0600 temporary files and removes them before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"attachment","type":"string","required":true,"description":"Cloud Interconnect attachment name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"region","type":"string","required":true,"description":"Attachment region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":5,"max":360}}],"examples":[{"title":"Last hour for a VLAN attachment","args":{"attachment":"va1-primary","project":"example-prod","region":"us-central1","window_minutes":60}}],"search_terms":["Interconnect saturation","VLAN attachment utilization"]},{"id":"gcp.log_entries","title":"Query recent Cloud Logging entries","summary":"Query the newest five recent Cloud Logging entries in a Google Cloud project, optionally narrowed by minimum severity, resource type, and exact log ID. Returns fixed, clipped diagnostic fields; log content is arbitrary application output, so redaction is best-effort and the result should be treated as sensitive diagnostics.","description":"Query the newest five recent Cloud Logging entries in a Google Cloud project, optionally narrowed by minimum severity, resource type, and exact log ID. Returns fixed, clipped diagnostic fields; log content is arbitrary application output, so redaction is best-effort and the result should be treated as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One gcloud token read and one read-only Cloud Logging API request.","Returns application-controlled log content into the governed run result and audit trail."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"minimum_severity","type":"string","required":false,"default":"DEFAULT","description":"Minimum normalized Cloud Logging severity to return.","validation":{"enum":["DEFAULT","DEBUG","INFO","NOTICE","WARNING","ERROR","CRITICAL","ALERT","EMERGENCY"]}},{"name":"resource_type","type":"string","required":false,"default":"","description":"Optional exact monitored-resource type, such as gce_instance or cloud_run_revision.","validation":{"pattern":"^([a-z][a-z0-9_]{0,127})?$","max_length":128}},{"name":"log_id","type":"string","required":false,"default":"","description":"Optional exact URL-encoded log ID, without the projects/PROJECT/logs/ prefix.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9._~%+/-]{0,511})?$","max_length":512}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"page_size","type":"integer","required":false,"default":5,"description":"Maximum entries to return.","validation":{"min":1,"max":5}}],"examples":[{"title":"Recent VM errors","args":{"minimum_severity":"ERROR","page_size":5,"project":"example-prod","resource_type":"gce_instance","window_minutes":60}}],"search_terms":["query gcp logs","find cloud logging errors","recent google cloud logs"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"entries":{"items":{"additionalProperties":false,"properties":{"log_name":{"maxLength":160,"type":"string"},"message":{"maxLength":200,"type":"string"},"message_truncated":{"type":"boolean"},"resource_type":{"maxLength":64,"type":"string"},"severity":{"maxLength":16,"type":"string"},"timestamp":{"maxLength":40,"type":"string"}},"required":["timestamp","severity","resource_type","log_name","message","message_truncated"],"type":"object"},"maxItems":5,"type":"array"},"more_available":{"type":"boolean"}},"required":["entries","more_available"],"type":"object"}},{"id":"gcp.log_names","title":"List Cloud Logging log names","summary":"List one bounded page of log names that contain entries in a Google Cloud project. Use the returned continuation cursor to inspect the next page.","description":"List one bounded page of log names that contain entries in a Google Cloud project. Use the returned continuation cursor to inspect the next page.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Cloud Logging API request.","Returns names only; no log entries or payloads are read."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"page_size","type":"integer","required":false,"default":8,"description":"Maximum log names in this page.","validation":{"min":1,"max":8}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation cursor from the previous result. Provider cursors containing unsupported characters or exceeding 1,024 bytes are omitted from output and cannot be continued through this action.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":1024}}],"examples":[{"title":"First page of project logs","args":{"page_size":8,"project":"example-prod"}}],"search_terms":["list gcp logs","discover cloud logging logs"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cursor_omitted":{"type":"boolean"},"log_names":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":240,"type":"string"},"truncated":{"type":"boolean"}},"required":["name","truncated"],"type":"object"},"maxItems":8,"type":"array"},"next_page_cursor":{"maxLength":1024,"type":["string","null"]}},"required":["log_names","next_page_cursor","cursor_omitted"],"type":"object"}},{"id":"gcp.metric_descriptors","title":"List Cloud Monitoring metric descriptors","summary":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a nextPageToken when another page exists.","description":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a nextPageToken when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","Result count is bounded by page_size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"type_prefix","type":"string","required":false,"default":"","description":"Optional metric-type prefix.","validation":{"pattern":"^([A-Za-z][A-Za-z0-9._/-]{0,255})?$"}},{"name":"active_only","type":"boolean","required":false,"default":true,"description":"Exclude descriptors with no recent data."},{"name":"page_size","type":"integer","required":false,"default":100,"description":"Maximum descriptors in this page.","validation":{"min":1,"max":500}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque nextPageToken from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Interconnect metric descriptors","args":{"active_only":true,"project":"example-prod","type_prefix":"interconnect.googleapis.com/"}}],"search_terms":[]},{"id":"gcp.metric_query","title":"Query Cloud Monitoring time series","summary":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a nextPageToken when another page exists.","description":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a nextPageToken when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","page_size caps returned points because the request uses view=FULL."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"metric_type","type":"string","required":true,"description":"Full metric type, such as compute.googleapis.com/instance/cpu/utilization.","validation":{"pattern":"^[A-Za-z](?:[A-Za-z0-9._/-]{0,510}[A-Za-z0-9])?$"}},{"name":"resource_filter","type":"string","required":false,"default":"","description":"Optional Monitoring filter expression appended to the fixed metric.type predicate.","validation":{"pattern":"^[ -~]*$","max_length":1024}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"alignment_seconds","type":"integer","required":false,"default":60,"description":"Alignment period when aligner is not ALIGN_NONE.","validation":{"min":60,"max":3600}},{"name":"aligner","type":"string","required":false,"default":"ALIGN_NONE","description":"Optional per-series aligner.","validation":{"enum":["ALIGN_NONE","ALIGN_DELTA","ALIGN_RATE","ALIGN_MEAN","ALIGN_MAX","ALIGN_MIN","ALIGN_SUM","ALIGN_NEXT_OLDER"]}},{"name":"page_size","type":"integer","required":false,"default":500,"description":"Maximum number of FULL-view points in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque nextPageToken from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"VM CPU for one instance","args":{"aligner":"ALIGN_MEAN","alignment_seconds":300,"metric_type":"compute.googleapis.com/instance/cpu/utilization","project":"example-prod","resource_filter":"resource.type = \"gce_instance\" AND resource.labels.instance_id = \"1234567890\"","window_minutes":60}}],"search_terms":[]}]},{"version":"0.3.0","content_hash":"sha256:943bca4673613766ba4ccb593673ffda5d33a91a925aca6d1c02fc1232886c48","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-monitoring/0.3.0/943bca4673613766ba4ccb593673ffda5d33a91a925aca6d1c02fc1232886c48/pack.tar.gz","actions":[{"id":"gcp.alert_policies","title":"gcloud monitoring policies list","summary":"List alerting policies in one Google Cloud project.","description":"List alerting policies in one Google Cloud project.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Monitoring API pagination.","Returned policies are capped by limit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project alert policies","args":{"limit":100,"project":"example-prod"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["monitoring","policies","list","--project={{ args.project }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.alert_policy_disable","title":"Disable a Cloud Monitoring alert policy","summary":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","description":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy stops alerting; its notification channels stay silent until re-enabled."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Silence a flapping alert policy during an incident","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["disable alert","silence policy","stop alerting"]},{"id":"gcp.alert_policy_enable","title":"Enable a Cloud Monitoring alert policy","summary":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","description":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy's conditions resume evaluating and can page its notification channels."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Re-enable a CPU alert policy after maintenance","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["enable alert","resume alerting","unsilence policy"]},{"id":"gcp.interconnect_utilization","title":"Query Cloud Interconnect attachment utilization","summary":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","description":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","kind":"script","risk":"low","side_effects":["One gcloud token read and three read-only Monitoring API requests.","Writes public metric responses to mode-0600 temporary files and removes them before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"attachment","type":"string","required":true,"description":"Cloud Interconnect attachment name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"region","type":"string","required":true,"description":"Attachment region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":5,"max":360}}],"examples":[{"title":"Last hour for a VLAN attachment","args":{"attachment":"va1-primary","project":"example-prod","region":"us-central1","window_minutes":60}}],"search_terms":["Interconnect saturation","VLAN attachment utilization"]},{"id":"gcp.log_entries","title":"Query recent Cloud Logging entries","summary":"Query the newest five recent Cloud Logging entries in a Google Cloud project, optionally narrowed by minimum severity, resource type, and exact log ID. Returns fixed, clipped diagnostic fields; log content is arbitrary application output, so redaction is best-effort and the result should be treated as sensitive diagnostics.","description":"Query the newest five recent Cloud Logging entries in a Google Cloud project, optionally narrowed by minimum severity, resource type, and exact log ID. Returns fixed, clipped diagnostic fields; log content is arbitrary application output, so redaction is best-effort and the result should be treated as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One gcloud token read and one read-only Cloud Logging API request.","Returns application-controlled log content into the governed run result and audit trail."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"minimum_severity","type":"string","required":false,"default":"DEFAULT","description":"Minimum normalized Cloud Logging severity to return.","validation":{"enum":["DEFAULT","DEBUG","INFO","NOTICE","WARNING","ERROR","CRITICAL","ALERT","EMERGENCY"]}},{"name":"resource_type","type":"string","required":false,"default":"","description":"Optional exact monitored-resource type, such as gce_instance or cloud_run_revision.","validation":{"pattern":"^([a-z][a-z0-9_]{0,127})?$","max_length":128}},{"name":"log_id","type":"string","required":false,"default":"","description":"Optional exact URL-encoded log ID, without the projects/PROJECT/logs/ prefix.","validation":{"pattern":"^([A-Za-z0-9][A-Za-z0-9._~%+/-]{0,511})?$","max_length":512}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"page_size","type":"integer","required":false,"default":5,"description":"Maximum entries to return.","validation":{"min":1,"max":5}}],"examples":[{"title":"Recent VM errors","args":{"minimum_severity":"ERROR","page_size":5,"project":"example-prod","resource_type":"gce_instance","window_minutes":60}}],"search_terms":["query gcp logs","find cloud logging errors","recent google cloud logs"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"entries":{"items":{"additionalProperties":false,"properties":{"log_name":{"maxLength":160,"type":"string"},"message":{"maxLength":200,"type":"string"},"message_truncated":{"type":"boolean"},"resource_type":{"maxLength":64,"type":"string"},"severity":{"maxLength":16,"type":"string"},"timestamp":{"maxLength":40,"type":"string"}},"required":["timestamp","severity","resource_type","log_name","message","message_truncated"],"type":"object"},"maxItems":5,"type":"array"},"more_available":{"type":"boolean"}},"required":["entries","more_available"],"type":"object"}},{"id":"gcp.log_names","title":"List Cloud Logging log names","summary":"List one bounded page of log names that contain entries in a Google Cloud project. Use the returned continuation cursor to inspect the next page.","description":"List one bounded page of log names that contain entries in a Google Cloud project. Use the returned continuation cursor to inspect the next page.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Cloud Logging API request.","Returns names only; no log entries or payloads are read."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"page_size","type":"integer","required":false,"default":8,"description":"Maximum log names in this page.","validation":{"min":1,"max":8}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation cursor from the previous result. Provider cursors containing unsupported characters or exceeding 1,024 bytes are omitted from output and cannot be continued through this action.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":1024}}],"examples":[{"title":"First page of project logs","args":{"page_size":8,"project":"example-prod"}}],"search_terms":["list gcp logs","discover cloud logging logs"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"cursor_omitted":{"type":"boolean"},"log_names":{"items":{"additionalProperties":false,"properties":{"name":{"maxLength":240,"type":"string"},"truncated":{"type":"boolean"}},"required":["name","truncated"],"type":"object"},"maxItems":8,"type":"array"},"next_page_cursor":{"maxLength":1024,"type":["string","null"]}},"required":["log_names","next_page_cursor","cursor_omitted"],"type":"object"}},{"id":"gcp.metric_descriptors","title":"List Cloud Monitoring metric descriptors","summary":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a nextPageToken when another page exists.","description":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a nextPageToken when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","Result count is bounded by page_size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"type_prefix","type":"string","required":false,"default":"","description":"Optional metric-type prefix.","validation":{"pattern":"^([A-Za-z][A-Za-z0-9._/-]{0,255})?$"}},{"name":"active_only","type":"boolean","required":false,"default":true,"description":"Exclude descriptors with no recent data."},{"name":"page_size","type":"integer","required":false,"default":100,"description":"Maximum descriptors in this page.","validation":{"min":1,"max":500}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque nextPageToken from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Interconnect metric descriptors","args":{"active_only":true,"project":"example-prod","type_prefix":"interconnect.googleapis.com/"}}],"search_terms":[]},{"id":"gcp.metric_query","title":"Query Cloud Monitoring time series","summary":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a nextPageToken when another page exists.","description":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a nextPageToken when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","page_size caps returned points because the request uses view=FULL."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"metric_type","type":"string","required":true,"description":"Full metric type, such as compute.googleapis.com/instance/cpu/utilization.","validation":{"pattern":"^[A-Za-z](?:[A-Za-z0-9._/-]{0,510}[A-Za-z0-9])?$"}},{"name":"resource_filter","type":"string","required":false,"default":"","description":"Optional Monitoring filter expression appended to the fixed metric.type predicate.","validation":{"pattern":"^[ -~]*$","max_length":1024}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"alignment_seconds","type":"integer","required":false,"default":60,"description":"Alignment period when aligner is not ALIGN_NONE.","validation":{"min":60,"max":3600}},{"name":"aligner","type":"string","required":false,"default":"ALIGN_NONE","description":"Optional per-series aligner.","validation":{"enum":["ALIGN_NONE","ALIGN_DELTA","ALIGN_RATE","ALIGN_MEAN","ALIGN_MAX","ALIGN_MIN","ALIGN_SUM","ALIGN_NEXT_OLDER"]}},{"name":"page_size","type":"integer","required":false,"default":500,"description":"Maximum number of FULL-view points in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque nextPageToken from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"VM CPU for one instance","args":{"aligner":"ALIGN_MEAN","alignment_seconds":300,"metric_type":"compute.googleapis.com/instance/cpu/utilization","project":"example-prod","resource_filter":"resource.type = \"gce_instance\" AND resource.labels.instance_id = \"1234567890\"","window_minutes":60}}],"search_terms":[]}]},{"version":"0.2.0","content_hash":"sha256:ab13b607bfdfc3583249d0c06a53daa06c3ed1c012aeaa97563f961bf33d892d","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-monitoring/0.2.0/ab13b607bfdfc3583249d0c06a53daa06c3ed1c012aeaa97563f961bf33d892d/pack.tar.gz","actions":[{"id":"gcp.alert_policies","title":"gcloud monitoring policies list","summary":"List alerting policies in one Google Cloud project.","description":"List alerting policies in one Google Cloud project.","kind":"exec","risk":"low","side_effects":["Read-only Cloud Monitoring API pagination.","Returned policies are capped by limit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum policies to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project alert policies","args":{"limit":100,"project":"example-prod"}}],"search_terms":[],"command":{"binary":"gcloud","argv":["monitoring","policies","list","--project={{ args.project }}","--limit={{ args.limit }}","--format=json","--quiet"]}},{"id":"gcp.alert_policy_disable","title":"Disable a Cloud Monitoring alert policy","summary":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","description":"Disable one exact alerting policy so its conditions stop evaluating and notifying. Incidents the policy would catch go unnoticed until it is re-enabled with gcp.alert_policy_enable — that is the rollback. Idempotent: disabling an already-disabled policy succeeds and changes nothing. Returns the updated policy.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy stops alerting; its notification channels stay silent until re-enabled."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Silence a flapping alert policy during an incident","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["disable alert","silence policy","stop alerting"]},{"id":"gcp.alert_policy_enable","title":"Enable a Cloud Monitoring alert policy","summary":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","description":"Enable one exact alerting policy so its conditions evaluate and notify again. Idempotent: enabling an already-enabled policy succeeds and changes nothing. Returns the updated policy; roll back with gcp.alert_policy_disable.","kind":"script","risk":"high","side_effects":["One gcloud token read and one Monitoring API PATCH restricted to the policy's enabled field.","The policy's conditions resume evaluating and can page its notification channels."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"policy","type":"string","required":true,"description":"Numeric alert-policy ID — the last segment of projects/PROJECT/alertPolicies/ID. Find it with gcp.alert_policies.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Re-enable a CPU alert policy after maintenance","args":{"policy":"8675309001234","project":"example-prod"}}],"search_terms":["enable alert","resume alerting","unsilence policy"]},{"id":"gcp.interconnect_utilization","title":"Query Cloud Interconnect attachment utilization","summary":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","description":"Query capacity plus received and sent byte rates for one Cloud Interconnect attachment, then calculate independent ingress and egress utilization ratios. The link is full duplex, so directions are never summed.","kind":"script","risk":"low","side_effects":["One gcloud token read and three read-only Monitoring API requests.","Writes public metric responses to mode-0600 temporary files and removes them before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"attachment","type":"string","required":true,"description":"Cloud Interconnect attachment name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$"}},{"name":"region","type":"string","required":true,"description":"Attachment region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$"}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":5,"max":360}}],"examples":[{"title":"Last hour for a VLAN attachment","args":{"attachment":"va1-primary","project":"example-prod","region":"us-central1","window_minutes":60}}],"search_terms":["Interconnect saturation","VLAN attachment utilization"]},{"id":"gcp.metric_descriptors","title":"List Cloud Monitoring metric descriptors","summary":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a nextPageToken when another page exists.","description":"List active metric descriptors in one project, optionally restricted to a metric-type prefix. Returns a nextPageToken when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","Result count is bounded by page_size."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"type_prefix","type":"string","required":false,"default":"","description":"Optional metric-type prefix.","validation":{"pattern":"^([A-Za-z][A-Za-z0-9._/-]{0,255})?$"}},{"name":"active_only","type":"boolean","required":false,"default":true,"description":"Exclude descriptors with no recent data."},{"name":"page_size","type":"integer","required":false,"default":100,"description":"Maximum descriptors in this page.","validation":{"min":1,"max":500}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque nextPageToken from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Interconnect metric descriptors","args":{"active_only":true,"project":"example-prod","type_prefix":"interconnect.googleapis.com/"}}],"search_terms":[]},{"id":"gcp.metric_query","title":"Query Cloud Monitoring time series","summary":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a nextPageToken when another page exists.","description":"Query one metric type over a bounded recent window, optionally narrowing by a Monitoring resource filter. Returns FULL time-series data and a nextPageToken when another page exists.","kind":"script","risk":"low","side_effects":["One gcloud token read and one read-only Monitoring API request.","page_size caps returned points because the request uses view=FULL."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$"}},{"name":"metric_type","type":"string","required":true,"description":"Full metric type, such as compute.googleapis.com/instance/cpu/utilization.","validation":{"pattern":"^[A-Za-z](?:[A-Za-z0-9._/-]{0,510}[A-Za-z0-9])?$"}},{"name":"resource_filter","type":"string","required":false,"default":"","description":"Optional Monitoring filter expression appended to the fixed metric.type predicate.","validation":{"pattern":"^[ -~]*$","max_length":1024}},{"name":"window_minutes","type":"integer","required":false,"default":60,"description":"Recent query window in minutes.","validation":{"min":1,"max":1440}},{"name":"alignment_seconds","type":"integer","required":false,"default":60,"description":"Alignment period when aligner is not ALIGN_NONE.","validation":{"min":60,"max":3600}},{"name":"aligner","type":"string","required":false,"default":"ALIGN_NONE","description":"Optional per-series aligner.","validation":{"enum":["ALIGN_NONE","ALIGN_DELTA","ALIGN_RATE","ALIGN_MEAN","ALIGN_MAX","ALIGN_MIN","ALIGN_SUM","ALIGN_NEXT_OLDER"]}},{"name":"page_size","type":"integer","required":false,"default":500,"description":"Maximum number of FULL-view points in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque nextPageToken from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"VM CPU for one instance","args":{"aligner":"ALIGN_MEAN","alignment_seconds":300,"metric_type":"compute.googleapis.com/instance/cpu/utilization","project":"example-prod","resource_filter":"resource.type = \"gce_instance\" AND resource.labels.instance_id = \"1234567890\"","window_minutes":60}}],"search_terms":[]}]}]},{"id":"gcp-networking","name":"Google Cloud networking diagnostics","version":"0.1.2","description":"Read-only Google Cloud VPC, subnet, firewall, route, address, Cloud Router, Cloud NAT, VPN, and Interconnect diagnostics. Outputs are fixed projections that omit arbitrary descriptions, labels, and credential-shaped fields.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-networking","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-networking","content_hash":"sha256:7fdb677f1c234fd64dcfbb4c8e8562f588877a2eb4dad25467702f6c849c087b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-networking/0.1.2/7fdb677f1c234fd64dcfbb4c8e8562f588877a2eb4dad25467702f6c849c087b/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the gcloud CLI on the runner host with an explicitly named project. Authenticate gcloud before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["The principal needs roles/compute.networkViewer or equivalent get/list permissions.","Any credential/config env must be allowlisted in the runner's `execution.inherit_env`; attached service accounts and workload identity need no credential env.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed.","Every action passes --quiet and an explicit --project so ambient project configuration cannot redirect a request."],"verify":"gcp.networks"},"actions":[{"id":"gcp.addresses","title":"gcloud compute addresses list","summary":"List bounded global and regional IP addresses, purposes, status, and consumers.","description":"List bounded global and regional IP addresses, purposes, status, and consumers.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum addresses to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project IP addresses","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.firewall_rules","title":"gcloud compute firewall-rules list","summary":"List bounded VPC firewall rules with match criteria and allow or deny actions.","description":"List bounded VPC firewall rules with match criteria and allow or deny actions.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum firewall rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project firewall rules","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.interconnect_attachments","title":"gcloud compute interconnects attachments list","summary":"List bounded Cloud Interconnect VLAN attachments and operational state.","description":"List bounded Cloud Interconnect VLAN attachments and operational state.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum attachments to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project VLAN attachments","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.interconnect_diagnostics","title":"gcloud compute interconnects get-diagnostics","summary":"Show LACP and physical-link diagnostics for one Dedicated Interconnect.","description":"Show LACP and physical-link diagnostics for one Dedicated Interconnect.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"interconnect","type":"string","required":true,"description":"Dedicated Interconnect name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Dedicated Interconnect diagnostics","args":{"interconnect":"primary","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.nat_describe","title":"gcloud compute routers nats describe","summary":"Show one Cloud NAT's address allocation, subnet coverage, logging, and rules.","description":"Show one Cloud NAT's address allocation, subnet coverage, logging, and rules.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"nat","type":"string","required":true,"description":"Cloud NAT name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"router","type":"string","required":true,"description":"Parent Cloud Router name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Router region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Application egress NAT","args":{"nat":"app-egress","project":"example-prod","region":"us-central1","router":"edge"}}],"search_terms":[]},{"id":"gcp.network_describe","title":"gcloud compute networks describe","summary":"Show one VPC network and its peering topology without arbitrary labels or descriptions.","description":"Show one VPC network and its peering topology without arbitrary labels or descriptions.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"network","type":"string","required":true,"description":"VPC network name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Application VPC","args":{"network":"app","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.networks","title":"gcloud compute networks list","summary":"List bounded VPC network topology without arbitrary labels or descriptions.","description":"List bounded VPC network topology without arbitrary labels or descriptions.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum networks to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project VPC networks","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.router_status","title":"gcloud compute routers get-status","summary":"Show BGP peer state and dynamic best routes for one Cloud Router.","description":"Show BGP peer state and dynamic best routes for one Cloud Router.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"router","type":"string","required":true,"description":"Cloud Router name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Router region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Router BGP status","args":{"project":"example-prod","region":"us-central1","router":"edge"}}],"search_terms":[]},{"id":"gcp.routers","title":"gcloud compute routers list","summary":"List bounded Cloud Routers with BGP and Cloud NAT attachment summaries.","description":"List bounded Cloud Routers with BGP and Cloud NAT attachment summaries.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum routers to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project Cloud Routers","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.routes","title":"gcloud compute routes list","summary":"List bounded non-dynamic VPC routes and their next hops.","description":"List bounded non-dynamic VPC routes and their next hops.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Dynamic routes are reported by router_status instead."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum routes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project routes","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.subnet_describe","title":"gcloud compute networks subnets describe","summary":"Show one regional subnet, including primary and secondary ranges.","description":"Show one regional subnet, including primary and secondary ranges.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"subnet","type":"string","required":true,"description":"Subnet name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Subnet region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Application subnet","args":{"project":"example-prod","region":"us-central1","subnet":"app"}}],"search_terms":[]},{"id":"gcp.subnets","title":"gcloud compute networks subnets list","summary":"List bounded subnet ranges, purposes, roles, and utilization-relevant state.","description":"List bounded subnet ranges, purposes, roles, and utilization-relevant state.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum subnets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project subnets","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.vpn_gateway_status","title":"gcloud compute vpn-gateways get-status","summary":"Show tunnel connection state for one HA VPN gateway.","description":"Show tunnel connection state for one HA VPN gateway.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"gateway","type":"string","required":true,"description":"HA VPN gateway name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Gateway region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"HA VPN status","args":{"gateway":"edge-vpn","project":"example-prod","region":"us-central1"}}],"search_terms":[]},{"id":"gcp.vpn_tunnels","title":"gcloud compute vpn-tunnels list","summary":"List bounded Cloud VPN tunnels, peer endpoints, selectors, and status.","description":"List bounded Cloud VPN tunnels, peer endpoints, selectors, and status.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum VPN tunnels to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project VPN tunnels","args":{"project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:8aeca131aa12cc7ee244a1c5bb7663a7434919e7f8a8406cd9206d0b9b02062f","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-networking/0.1.0/8aeca131aa12cc7ee244a1c5bb7663a7434919e7f8a8406cd9206d0b9b02062f/pack.tar.gz","actions":[{"id":"gcp.addresses","title":"gcloud compute addresses list","summary":"List bounded global and regional IP addresses, purposes, status, and consumers.","description":"List bounded global and regional IP addresses, purposes, status, and consumers.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum addresses to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project IP addresses","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.firewall_rules","title":"gcloud compute firewall-rules list","summary":"List bounded VPC firewall rules with match criteria and allow or deny actions.","description":"List bounded VPC firewall rules with match criteria and allow or deny actions.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum firewall rules to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project firewall rules","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.interconnect_attachments","title":"gcloud compute interconnects attachments list","summary":"List bounded Cloud Interconnect VLAN attachments and operational state.","description":"List bounded Cloud Interconnect VLAN attachments and operational state.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum attachments to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project VLAN attachments","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.interconnect_diagnostics","title":"gcloud compute interconnects get-diagnostics","summary":"Show LACP and physical-link diagnostics for one Dedicated Interconnect.","description":"Show LACP and physical-link diagnostics for one Dedicated Interconnect.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"interconnect","type":"string","required":true,"description":"Dedicated Interconnect name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Dedicated Interconnect diagnostics","args":{"interconnect":"primary","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.nat_describe","title":"gcloud compute routers nats describe","summary":"Show one Cloud NAT's address allocation, subnet coverage, logging, and rules.","description":"Show one Cloud NAT's address allocation, subnet coverage, logging, and rules.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"nat","type":"string","required":true,"description":"Cloud NAT name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"router","type":"string","required":true,"description":"Parent Cloud Router name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Router region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Application egress NAT","args":{"nat":"app-egress","project":"example-prod","region":"us-central1","router":"edge"}}],"search_terms":[]},{"id":"gcp.network_describe","title":"gcloud compute networks describe","summary":"Show one VPC network and its peering topology without arbitrary labels or descriptions.","description":"Show one VPC network and its peering topology without arbitrary labels or descriptions.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"network","type":"string","required":true,"description":"VPC network name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}}],"examples":[{"title":"Application VPC","args":{"network":"app","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.networks","title":"gcloud compute networks list","summary":"List bounded VPC network topology without arbitrary labels or descriptions.","description":"List bounded VPC network topology without arbitrary labels or descriptions.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum networks to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project VPC networks","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.router_status","title":"gcloud compute routers get-status","summary":"Show BGP peer state and dynamic best routes for one Cloud Router.","description":"Show BGP peer state and dynamic best routes for one Cloud Router.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"router","type":"string","required":true,"description":"Cloud Router name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Router region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Router BGP status","args":{"project":"example-prod","region":"us-central1","router":"edge"}}],"search_terms":[]},{"id":"gcp.routers","title":"gcloud compute routers list","summary":"List bounded Cloud Routers with BGP and Cloud NAT attachment summaries.","description":"List bounded Cloud Routers with BGP and Cloud NAT attachment summaries.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum routers to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project Cloud Routers","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.routes","title":"gcloud compute routes list","summary":"List bounded non-dynamic VPC routes and their next hops.","description":"List bounded non-dynamic VPC routes and their next hops.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination.","Dynamic routes are reported by router_status instead."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum routes to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project routes","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.subnet_describe","title":"gcloud compute networks subnets describe","summary":"Show one regional subnet, including primary and secondary ranges.","description":"Show one regional subnet, including primary and secondary ranges.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"subnet","type":"string","required":true,"description":"Subnet name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Subnet region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"Application subnet","args":{"project":"example-prod","region":"us-central1","subnet":"app"}}],"search_terms":[]},{"id":"gcp.subnets","title":"gcloud compute networks subnets list","summary":"List bounded subnet ranges, purposes, roles, and utilization-relevant state.","description":"List bounded subnet ranges, purposes, roles, and utilization-relevant state.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum subnets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project subnets","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.vpn_gateway_status","title":"gcloud compute vpn-gateways get-status","summary":"Show tunnel connection state for one HA VPN gateway.","description":"Show tunnel connection state for one HA VPN gateway.","kind":"script","risk":"low","side_effects":["One read-only Compute Engine API call."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"gateway","type":"string","required":true,"description":"HA VPN gateway name.","validation":{"pattern":"^[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$","max_length":63}},{"name":"region","type":"string","required":true,"description":"Gateway region.","validation":{"pattern":"^[a-z0-9][a-z0-9-]{0,62}$","max_length":63}}],"examples":[{"title":"HA VPN status","args":{"gateway":"edge-vpn","project":"example-prod","region":"us-central1"}}],"search_terms":[]},{"id":"gcp.vpn_tunnels","title":"gcloud compute vpn-tunnels list","summary":"List bounded Cloud VPN tunnels, peer endpoints, selectors, and status.","description":"List bounded Cloud VPN tunnels, peer endpoints, selectors, and status.","kind":"script","risk":"low","side_effects":["Read-only Compute Engine API pagination."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum VPN tunnels to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project VPN tunnels","args":{"project":"example-prod"}}],"search_terms":[]}]}]},{"id":"gcp-storage","name":"Google Cloud Storage diagnostics","version":"0.1.1","description":"Read-only Cloud Storage diagnostics for buckets, IAM policies, bounded object listings, and fixed object metadata. Object bodies, custom metadata values, contexts, signed URLs, and credential operations are excluded.","vendor":"emisar","homepage":"https://emisar.dev/packs/gcp-storage","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/gcp-storage","content_hash":"sha256:e863ce00f34dd53ed8721758aee31522c7d64ba5349c9bfb47a52b48eda00cf6","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-storage/0.1.1/e863ce00f34dd53ed8721758aee31522c7d64ba5349c9bfb47a52b48eda00cf6/pack.tar.gz","requires":{"os":["linux"],"binaries":["gcloud","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives gcloud and projects Cloud Storage API responses locally before they leave the runner. Authenticate gcloud before loading the pack.","env":[{"name":"CLOUDSDK_CONFIG","description":"Optional gcloud configuration directory.","example":"/etc/emisar/gcloud"},{"name":"CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE","description":"Optional credential file that overrides the active gcloud account.","example":"/etc/emisar/gcp-reader.json"}],"notes":["Bucket/object inventory can use roles/storage.bucketViewer plus roles/storage.objectViewer; bucket IAM reads additionally need storage.buckets.getIamPolicy, best supplied through an exact custom read role rather than roles/storage.admin.","Actions use mode-0600 temporary response files and remove them before exit.","Object actions return metadata only and never fetch object bodies.","This remote-target pack declares no host detection signal and is never auto-suggested merely because gcloud is installed."],"verify":"gcp.storage_buckets"},"actions":[{"id":"gcp.storage_bucket_describe","title":"gcloud storage buckets describe","summary":"Show one bucket's location, storage, retention, lifecycle, encryption, access, and namespace configuration.","description":"Show one bucket's location, storage, retention, lifecycle, encryption, access, and namespace configuration.","kind":"script","risk":"low","side_effects":["One read-only Cloud Storage API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}}],"examples":[{"title":"Application bucket","args":{"bucket":"example-prod-assets","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_bucket_policy","title":"gcloud storage buckets get-iam-policy","summary":"Show one bucket's IAM roles, members, and conditions.","description":"Show one bucket's IAM roles, members, and conditions.","kind":"script","risk":"low","side_effects":["One read-only Cloud Storage IAM API call.","Returns principal identities.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}}],"examples":[{"title":"Application bucket policy","args":{"bucket":"example-prod-assets","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_buckets","title":"gcloud storage buckets list","summary":"List bounded bucket location, storage, retention, lifecycle, encryption, access, and namespace configuration.","description":"List bounded bucket location, storage, retention, lifecycle, encryption, access, and namespace configuration.","kind":"script","risk":"low","side_effects":["Read-only Cloud Storage API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum buckets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project buckets","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_object_describe","title":"gcloud storage objects describe","summary":"Show one object's system metadata and custom metadata keys without its body or custom values.","description":"Show one object's system metadata and custom metadata keys without its body or custom values.","kind":"script","risk":"low","side_effects":["One read-only Cloud Storage metadata API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}},{"name":"key","type":"string","required":true,"description":"Literal object name; wildcard characters are rejected.","validation":{"pattern":"^[A-Za-z0-9!_.$'()+,;=:@%/ -]+$","max_length":1024}}],"examples":[{"title":"Application log object","args":{"bucket":"example-prod-assets","key":"logs/app.log","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_objects","title":"gcloud storage objects list","summary":"List bounded object system metadata under a literal prefix without custom metadata values.","description":"List bounded object system metadata under a literal prefix without custom metadata values.","kind":"script","risk":"low","side_effects":["Read-only Cloud Storage API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}},{"name":"prefix","type":"string","required":false,"default":"","description":"Literal object-name prefix; wildcard characters are rejected.","validation":{"pattern":"^[A-Za-z0-9!_.$'()+,;=:@%/ -]*$","max_length":1024}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum objects to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application logs","args":{"bucket":"example-prod-assets","prefix":"logs/","project":"example-prod"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:976ede94963f134ef0cca63eedd4bdb2dedde67d8e820feceac5a5a9c79a306b","tarball_url":"https://registry.emisar.dev/v1/packs/gcp-storage/0.1.0/976ede94963f134ef0cca63eedd4bdb2dedde67d8e820feceac5a5a9c79a306b/pack.tar.gz","actions":[{"id":"gcp.storage_bucket_describe","title":"gcloud storage buckets describe","summary":"Show one bucket's location, storage, retention, lifecycle, encryption, access, and namespace configuration.","description":"Show one bucket's location, storage, retention, lifecycle, encryption, access, and namespace configuration.","kind":"script","risk":"low","side_effects":["One read-only Cloud Storage API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}}],"examples":[{"title":"Application bucket","args":{"bucket":"example-prod-assets","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_bucket_policy","title":"gcloud storage buckets get-iam-policy","summary":"Show one bucket's IAM roles, members, and conditions.","description":"Show one bucket's IAM roles, members, and conditions.","kind":"script","risk":"low","side_effects":["One read-only Cloud Storage IAM API call.","Returns principal identities.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}}],"examples":[{"title":"Application bucket policy","args":{"bucket":"example-prod-assets","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_buckets","title":"gcloud storage buckets list","summary":"List bounded bucket location, storage, retention, lifecycle, encryption, access, and namespace configuration.","description":"List bounded bucket location, storage, retention, lifecycle, encryption, access, and namespace configuration.","kind":"script","risk":"low","side_effects":["Read-only Cloud Storage API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum buckets to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Project buckets","args":{"project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_object_describe","title":"gcloud storage objects describe","summary":"Show one object's system metadata and custom metadata keys without its body or custom values.","description":"Show one object's system metadata and custom metadata keys without its body or custom values.","kind":"script","risk":"low","side_effects":["One read-only Cloud Storage metadata API call.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}},{"name":"key","type":"string","required":true,"description":"Literal object name; wildcard characters are rejected.","validation":{"pattern":"^[A-Za-z0-9!_.$'()+,;=:@%/ -]+$","max_length":1024}}],"examples":[{"title":"Application log object","args":{"bucket":"example-prod-assets","key":"logs/app.log","project":"example-prod"}}],"search_terms":[]},{"id":"gcp.storage_objects","title":"gcloud storage objects list","summary":"List bounded object system metadata under a literal prefix without custom metadata values.","description":"List bounded object system metadata under a literal prefix without custom metadata values.","kind":"script","risk":"low","side_effects":["Read-only Cloud Storage API pagination.","Uses a mode-0600 temporary response file and removes it before exit."],"args":[{"name":"project","type":"string","required":true,"description":"Google Cloud project ID.","validation":{"pattern":"^[a-z][a-z0-9-]{4,28}[a-z0-9]$","max_length":30}},{"name":"bucket","type":"string","required":true,"description":"Cloud Storage bucket name.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{1,61}[a-z0-9]$","max_length":63}},{"name":"prefix","type":"string","required":false,"default":"","description":"Literal object-name prefix; wildcard characters are rejected.","validation":{"pattern":"^[A-Za-z0-9!_.$'()+,;=:@%/ -]*$","max_length":1024}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum objects to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Application logs","args":{"bucket":"example-prod-assets","prefix":"logs/","project":"example-prod"}}],"search_terms":[]}]}]},{"id":"git-local","name":"Host-side git","version":"0.1.10","description":"Read-only git operations against a checkout living on the runner host (e.g. /opt/myapp). For remote-GitHub-API work, see the `github-cli` pack. The repo directory must live at GIT_REPO env var on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/git-local","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/git-local","content_hash":"sha256:6c38f3cd3b01664032cb4a4911a02fa5e2e5bd73580fdc451562d08043072d81","tarball_url":"https://registry.emisar.dev/v1/packs/git-local/0.1.10/6c38f3cd3b01664032cb4a4911a02fa5e2e5bd73580fdc451562d08043072d81/pack.tar.gz","requires":{"os":["linux"],"binaries":["git"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Runs read-only git commands against a checkout on the runner host — no credentials needed (nothing fetches or pushes to a remote).","env":[{"name":"GIT_REPO","required":true,"description":"Absolute path to the git checkout on the runner host that every action operates in. Add it to the runner's `inherit_env`.","example":"/opt/myapp"}],"notes":["The runner uid must own the repository or receive read/traverse access through its group or a persistent ACL. Git's safe.directory only accepts different ownership; it does not grant filesystem access. For another user's private checkout, install a dedicated runner as that owner."],"verify":"git.status"},"actions":[{"id":"git.blame_file","title":"git blame -- <path>","summary":"Show per-line authorship for one file. Path is relative to repo root.","description":"Show per-line authorship for one file. Path is relative to repo root.","kind":"exec","risk":"low","side_effects":["One git blame.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Path relative to repo root.","validation":{"pattern":"^[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*(/[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*)*$","max_length":512}}],"examples":[{"title":"Blame config/runtime.exs","args":{"path":"config/runtime.exs"}}],"search_terms":["who changed this line"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git blame -- \"$1\"","emisar","{{ args.path }}"]}},{"id":"git.branch_list","title":"git branch -av","summary":"List all branches (local + remote-tracking) with last commit.","description":"List all branches (local + remote-tracking) with last commit.","kind":"exec","risk":"low","side_effects":["One git branch.","Read-only."],"args":[],"examples":[{"title":"All branches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git branch -av"]}},{"id":"git.diff_head","title":"git diff HEAD","summary":"Show uncommitted changes against HEAD. Capped at 1MB of output.","description":"Show uncommitted changes against HEAD. Capped at 1MB of output.","kind":"exec","risk":"low","side_effects":["One git diff.","Read-only."],"args":[],"examples":[{"title":"Uncommitted changes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git diff HEAD"]}},{"id":"git.log_recent","title":"git log -n <N>","summary":"List the last N commits with author + date + subject.","description":"List the last N commits with author + date + subject.","kind":"exec","risk":"low","side_effects":["One git log.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":20,"description":"Number of commits.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent 20 commits","args":{}}],"search_terms":["what changed recently"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git log -n {{ args.count }} --pretty=format:'%h %ad %an %s' --date=iso"]}},{"id":"git.reflog","title":"git reflog -n <N>","summary":"Show local HEAD-movement history. Use to find recent rebases / resets.","description":"Show local HEAD-movement history. Use to find recent rebases / resets.","kind":"exec","risk":"low","side_effects":["One git reflog.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":30,"description":"Entries.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 30 HEAD moves","args":{}}],"search_terms":["lost commits","recover commit"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git reflog -n {{ args.count }}"]}},{"id":"git.remote_list","title":"git remote -v","summary":"List the remote URLs (fetch + push).","description":"List the remote URLs (fetch + push).","kind":"exec","risk":"low","side_effects":["One git remote.","Read-only."],"args":[],"examples":[{"title":"Remotes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git remote -v"]}},{"id":"git.show_commit","title":"git show <ref>","summary":"Show the commit message + diff for one commit ref.","description":"Show the commit message + diff for one commit ref.","kind":"exec","risk":"low","side_effects":["One git show.","Read-only."],"args":[{"name":"ref","type":"string","required":true,"description":"Commit ref (SHA, tag, HEAD~N).","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_.~^/\\-]{0,127}$"}}],"examples":[{"title":"Show HEAD","args":{"ref":"HEAD"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git show \"$1\"","emisar","{{ args.ref }}"]}},{"id":"git.status","title":"git status (porcelain)","summary":"Show working-tree status — uncommitted changes, branch, ahead/behind.","description":"Show working-tree status — uncommitted changes, branch, ahead/behind.","kind":"exec","risk":"low","side_effects":["One git status.","Read-only."],"args":[],"examples":[{"title":"Working tree status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git status --branch --porcelain=v1"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:477841b2cb43e530ad4a892d9c0e789d6272b1702ac99e3dc70063c0bdcc516c","tarball_url":"https://registry.emisar.dev/v1/packs/git-local/0.1.9/477841b2cb43e530ad4a892d9c0e789d6272b1702ac99e3dc70063c0bdcc516c/pack.tar.gz","actions":[{"id":"git.blame_file","title":"git blame -- <path>","summary":"Show per-line authorship for one file. Path is relative to repo root.","description":"Show per-line authorship for one file. Path is relative to repo root.","kind":"exec","risk":"low","side_effects":["One git blame.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Path relative to repo root.","validation":{"pattern":"^[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*(/[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*)*$","max_length":512}}],"examples":[{"title":"Blame config/runtime.exs","args":{"path":"config/runtime.exs"}}],"search_terms":["who changed this line"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git blame -- \"$1\"","emisar","{{ args.path }}"]}},{"id":"git.branch_list","title":"git branch -av","summary":"List all branches (local + remote-tracking) with last commit.","description":"List all branches (local + remote-tracking) with last commit.","kind":"exec","risk":"low","side_effects":["One git branch.","Read-only."],"args":[],"examples":[{"title":"All branches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git branch -av"]}},{"id":"git.diff_head","title":"git diff HEAD","summary":"Show uncommitted changes against HEAD. Capped at 1MB of output.","description":"Show uncommitted changes against HEAD. Capped at 1MB of output.","kind":"exec","risk":"low","side_effects":["One git diff.","Read-only."],"args":[],"examples":[{"title":"Uncommitted changes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git diff HEAD"]}},{"id":"git.log_recent","title":"git log -n <N>","summary":"List the last N commits with author + date + subject.","description":"List the last N commits with author + date + subject.","kind":"exec","risk":"low","side_effects":["One git log.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":20,"description":"Number of commits.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent 20 commits","args":{}}],"search_terms":["what changed recently"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git log -n {{ args.count }} --pretty=format:'%h %ad %an %s' --date=iso"]}},{"id":"git.reflog","title":"git reflog -n <N>","summary":"Show local HEAD-movement history. Use to find recent rebases / resets.","description":"Show local HEAD-movement history. Use to find recent rebases / resets.","kind":"exec","risk":"low","side_effects":["One git reflog.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":30,"description":"Entries.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 30 HEAD moves","args":{}}],"search_terms":["lost commits","recover commit"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git reflog -n {{ args.count }}"]}},{"id":"git.remote_list","title":"git remote -v","summary":"List the remote URLs (fetch + push).","description":"List the remote URLs (fetch + push).","kind":"exec","risk":"low","side_effects":["One git remote.","Read-only."],"args":[],"examples":[{"title":"Remotes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git remote -v"]}},{"id":"git.show_commit","title":"git show <ref>","summary":"Show the commit message + diff for one commit ref.","description":"Show the commit message + diff for one commit ref.","kind":"exec","risk":"low","side_effects":["One git show.","Read-only."],"args":[{"name":"ref","type":"string","required":true,"description":"Commit ref (SHA, tag, HEAD~N).","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_.~^/\\-]{0,127}$"}}],"examples":[{"title":"Show HEAD","args":{"ref":"HEAD"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git show \"$1\"","emisar","{{ args.ref }}"]}},{"id":"git.status","title":"git status (porcelain)","summary":"Show working-tree status — uncommitted changes, branch, ahead/behind.","description":"Show working-tree status — uncommitted changes, branch, ahead/behind.","kind":"exec","risk":"low","side_effects":["One git status.","Read-only."],"args":[],"examples":[{"title":"Working tree status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git status --branch --porcelain=v1"]}}]},{"version":"0.1.7","content_hash":"sha256:c662588442554b89e93d002d0b35739c3fbe90edd9a84bf4ec611e88d99d4e38","tarball_url":"https://registry.emisar.dev/v1/packs/git-local/0.1.7/c662588442554b89e93d002d0b35739c3fbe90edd9a84bf4ec611e88d99d4e38/pack.tar.gz","actions":[{"id":"git.blame_file","title":"git blame -- <path>","summary":"Show per-line authorship for one file. Path is relative to repo root.","description":"Show per-line authorship for one file. Path is relative to repo root.","kind":"exec","risk":"low","side_effects":["One git blame.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Path relative to repo root.","validation":{"pattern":"^[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*(/[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*)*$","max_length":512}}],"examples":[{"title":"Blame config/runtime.exs","args":{"path":"config/runtime.exs"}}],"search_terms":["who changed this line"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git blame -- \"$1\"","emisar","{{ args.path }}"]}},{"id":"git.branch_list","title":"git branch -av","summary":"List all branches (local + remote-tracking) with last commit.","description":"List all branches (local + remote-tracking) with last commit.","kind":"exec","risk":"low","side_effects":["One git branch.","Read-only."],"args":[],"examples":[{"title":"All branches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git branch -av"]}},{"id":"git.diff_head","title":"git diff HEAD","summary":"Show uncommitted changes against HEAD. Capped at 1MB of output.","description":"Show uncommitted changes against HEAD. Capped at 1MB of output.","kind":"exec","risk":"low","side_effects":["One git diff.","Read-only."],"args":[],"examples":[{"title":"Uncommitted changes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git diff HEAD"]}},{"id":"git.log_recent","title":"git log -n <N>","summary":"List the last N commits with author + date + subject.","description":"List the last N commits with author + date + subject.","kind":"exec","risk":"low","side_effects":["One git log.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":20,"description":"Number of commits.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent 20 commits","args":{}}],"search_terms":["what changed recently"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git log -n {{ args.count }} --pretty=format:'%h %ad %an %s' --date=iso"]}},{"id":"git.reflog","title":"git reflog -n <N>","summary":"Show local HEAD-movement history. Use to find recent rebases / resets.","description":"Show local HEAD-movement history. Use to find recent rebases / resets.","kind":"exec","risk":"low","side_effects":["One git reflog.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":30,"description":"Entries.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 30 HEAD moves","args":{}}],"search_terms":["lost commits","recover commit"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git reflog -n {{ args.count }}"]}},{"id":"git.remote_list","title":"git remote -v","summary":"List the remote URLs (fetch + push).","description":"List the remote URLs (fetch + push).","kind":"exec","risk":"low","side_effects":["One git remote.","Read-only."],"args":[],"examples":[{"title":"Remotes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git remote -v"]}},{"id":"git.show_commit","title":"git show <ref>","summary":"Show the commit message + diff for one commit ref.","description":"Show the commit message + diff for one commit ref.","kind":"exec","risk":"low","side_effects":["One git show.","Read-only."],"args":[{"name":"ref","type":"string","required":true,"description":"Commit ref (SHA, tag, HEAD~N).","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_.~^/\\-]{0,127}$"}}],"examples":[{"title":"Show HEAD","args":{"ref":"HEAD"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git show \"$1\"","emisar","{{ args.ref }}"]}},{"id":"git.status","title":"git status (porcelain)","summary":"Show working-tree status — uncommitted changes, branch, ahead/behind.","description":"Show working-tree status — uncommitted changes, branch, ahead/behind.","kind":"exec","risk":"low","side_effects":["One git status.","Read-only."],"args":[],"examples":[{"title":"Working tree status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git status --branch --porcelain=v1"]}}]},{"version":"0.1.6","content_hash":"sha256:1a65266981600f3c86a7f5f2a5405a02ac5db4d82345acedcad1f50bee8d17c1","tarball_url":"https://registry.emisar.dev/v1/packs/git-local/0.1.6/1a65266981600f3c86a7f5f2a5405a02ac5db4d82345acedcad1f50bee8d17c1/pack.tar.gz","actions":[{"id":"git.blame_file","title":"git blame -- <path>","summary":"Show per-line authorship for one file. Path is relative to repo root.","description":"Show per-line authorship for one file. Path is relative to repo root.","kind":"exec","risk":"low","side_effects":["One git blame.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Path relative to repo root.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,512}$"}}],"examples":[{"title":"Blame config/runtime.exs","args":{"path":"config/runtime.exs"}}],"search_terms":["who changed this line"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git blame -- \"$1\"","emisar","{{ args.path }}"]}},{"id":"git.branch_list","title":"git branch -av","summary":"List all branches (local + remote-tracking) with last commit.","description":"List all branches (local + remote-tracking) with last commit.","kind":"exec","risk":"low","side_effects":["One git branch.","Read-only."],"args":[],"examples":[{"title":"All branches","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git branch -av"]}},{"id":"git.diff_head","title":"git diff HEAD","summary":"Show uncommitted changes against HEAD. Capped at 1MB of output.","description":"Show uncommitted changes against HEAD. Capped at 1MB of output.","kind":"exec","risk":"low","side_effects":["One git diff.","Read-only."],"args":[],"examples":[{"title":"Uncommitted changes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git diff HEAD"]}},{"id":"git.log_recent","title":"git log -n <N>","summary":"List the last N commits with author + date + subject.","description":"List the last N commits with author + date + subject.","kind":"exec","risk":"low","side_effects":["One git log.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":20,"description":"Number of commits.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent 20 commits","args":{}}],"search_terms":["what changed recently"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git log -n {{ args.count }} --pretty=format:'%h %ad %an %s' --date=iso"]}},{"id":"git.reflog","title":"git reflog -n <N>","summary":"Show local HEAD-movement history. Use to find recent rebases / resets.","description":"Show local HEAD-movement history. Use to find recent rebases / resets.","kind":"exec","risk":"low","side_effects":["One git reflog.","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":30,"description":"Entries.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 30 HEAD moves","args":{}}],"search_terms":["lost commits","recover commit"],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git reflog -n {{ args.count }}"]}},{"id":"git.remote_list","title":"git remote -v","summary":"List the remote URLs (fetch + push).","description":"List the remote URLs (fetch + push).","kind":"exec","risk":"low","side_effects":["One git remote.","Read-only."],"args":[],"examples":[{"title":"Remotes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git remote -v"]}},{"id":"git.show_commit","title":"git show <ref>","summary":"Show the commit message + diff for one commit ref.","description":"Show the commit message + diff for one commit ref.","kind":"exec","risk":"low","side_effects":["One git show.","Read-only."],"args":[{"name":"ref","type":"string","required":true,"description":"Commit ref (SHA, tag, HEAD~N).","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9_.~^/\\-]{0,127}$"}}],"examples":[{"title":"Show HEAD","args":{"ref":"HEAD"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git show \"$1\"","emisar","{{ args.ref }}"]}},{"id":"git.status","title":"git status (porcelain)","summary":"Show working-tree status — uncommitted changes, branch, ahead/behind.","description":"Show working-tree status — uncommitted changes, branch, ahead/behind.","kind":"exec","risk":"low","side_effects":["One git status.","Read-only."],"args":[],"examples":[{"title":"Working tree status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$GIT_REPO\" && git status --branch --porcelain=v1"]}}]}],"retired_below":"0.1.4"},{"id":"github-cli","name":"GitHub CLI operations","version":"0.1.15","description":"GitHub introspection — PRs, issues, repos, workflow runs, releases, commit checks, search — plus operator actions: merge PR, close PR, rerun workflow, dispatch workflow. Authenticates via the runner host's `gh auth status` token (i.e. ~/.config/gh).","vendor":"emisar","homepage":"https://emisar.dev/packs/github-cli","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/github-cli","content_hash":"sha256:776446ac4e6c6f10765c65c9f2ca8a95220594b88844e49c478d0c54b606dfa6","tarball_url":"https://registry.emisar.dev/v1/packs/github-cli/0.1.15/776446ac4e6c6f10765c65c9f2ca8a95220594b88844e49c478d0c54b606dfa6/pack.tar.gz","requires":{"os":["linux"],"binaries":["gh"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Actions shell out to gh on the runner host. gh authenticates with `GH_TOKEN` (or `GITHUB_TOKEN`) if set, otherwise with the token stored by `gh auth login`. Provide one of those so gh is signed in.","env":[{"name":"GH_TOKEN","description":"GitHub token gh uses to authenticate. Omit if the runner host is already signed in via `gh auth login`."}],"notes":["[Create a classic token with the repo scope preselected](https://github.com/settings/tokens/new?scopes=repo&description=emisar%20runner). Classic tokens have no read-only repo scope, so `repo` is the floor for reading private repositories and is what `repo_clone_count` needs (GitHub's traffic API requires push access); a fine-grained token limited to chosen repositories, with read-only Contents, Pull requests, and Actions, is narrower when you enable only the reads.","Token-free alternative: run `gh auth login` as the runner's user once; the credential is stored in `~/.config/gh/hosts.yml` and read from disk, so it needs no `inherit_env` entry.","The token needs repo read scope for the introspection actions; the mutators (pr_merge, pr_close, workflow_rerun, workflow_dispatch) and repo_clone_count need write/push access to the target repo."],"verify":"gh.auth_status"},"actions":[{"id":"gh.auth_status","title":"gh auth status","summary":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","description":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","kind":"exec","risk":"low","side_effects":["One API call to /user.","Read-only."],"args":[],"examples":[{"title":"Who am I?","args":{}}],"search_terms":[],"command":{"binary":"gh","argv":["auth","status"]}},{"id":"gh.branch_list","title":"gh api repos/<repo>/branches","summary":"List branches in the repo (paginated, up to 100).","description":"List branches in the repo (paginated, up to 100).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Branches","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/branches?per_page=100"]}},{"id":"gh.issue_list","title":"gh issue list","summary":"List open issues for one repo.","description":"List open issues for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | all.","validation":{"enum":["open","closed","all"]}}],"examples":[{"title":"Open issues","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,labels,createdAt,updatedAt"]}},{"id":"gh.issue_view","title":"gh issue view","summary":"Show details + comments for one issue.","description":"Show details + comments for one issue.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"issue","type":"integer","required":true,"description":"Issue number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One issue","args":{"issue":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","view","{{ args.issue }}","--repo","{{ args.repo }}","--comments","--json","number,title,body,state,author,labels,comments,createdAt"]}},{"id":"gh.pr_checks","title":"gh pr checks","summary":"List all CI checks for one PR + pass/fail status.","description":"List all CI checks for one PR + pass/fail status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"PR checks","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":["checks red"],"command":{"binary":"gh","argv":["pr","checks","{{ args.pr }}","--repo","{{ args.repo }}"]}},{"id":"gh.pr_close","title":"gh pr close <num>","summary":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","description":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","kind":"exec","risk":"medium","side_effects":["PR state set to closed.","PR branch unchanged.","Notifications fire."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"Close a stale PR","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","close","{{ args.pr }}"]}},{"id":"gh.pr_list","title":"gh pr list","summary":"List open PRs for one repo.","description":"List open PRs for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | merged | all.","validation":{"enum":["open","closed","merged","all"]}}],"examples":[{"title":"Open PRs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,createdAt,updatedAt,mergeable,reviewDecision"]}},{"id":"gh.pr_merge","title":"gh pr merge <num> --<method>","summary":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","description":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","kind":"exec","risk":"high","side_effects":["PR merged into the base branch.","main/master CI pipeline likely triggers.","PR branch may be auto-deleted depending on repo settings."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}},{"name":"method","type":"string","required":false,"default":"squash","description":"Merge method.","validation":{"enum":["squash","merge","rebase"]}}],"examples":[{"title":"Squash-merge PR 1234","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","merge","{{ args.pr }}","--{{ args.method }}"]}},{"id":"gh.pr_view","title":"gh pr view","summary":"Show details for one PR — title, body, status, reviews, checks.","description":"Show details for one PR — title, body, status, reviews, checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One PR","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","view","{{ args.pr }}","--repo","{{ args.repo }}","--json","number,title,body,state,author,createdAt,mergedAt,reviewDecision,statusCheckRollup"]}},{"id":"gh.release_list","title":"gh release list","summary":"List recent releases.","description":"List recent releases.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Releases","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["release","list","--repo","{{ args.repo }}","--limit","20"]}},{"id":"gh.repo_clone_count","title":"gh api repos/<repo>/traffic/clones","summary":"Show last-14-day clone counts (requires push access on the repo).","description":"Show last-14-day clone counts (requires push access on the repo).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Clone traffic","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/traffic/clones"]}},{"id":"gh.repo_view","title":"gh repo view","summary":"Show repo summary — description, stars, default branch, latest release.","description":"Show repo summary — description, stars, default branch, latest release.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,39}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Repo summary","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["repo","view","{{ args.repo }}","--json","name,description,defaultBranchRef,stargazerCount,forkCount,latestRelease,isArchived,isPrivate"]}},{"id":"gh.search_prs","title":"gh search prs","summary":"Search PRs across all of GitHub by query.","description":"Search PRs across all of GitHub by query.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"GitHub search syntax (e.g. \"repo:owner/name author:foo state:open\").","validation":{"pattern":"^.{1,512}$"}}],"examples":[{"title":"My open PRs","args":{"query":"author:@me state:open"}}],"search_terms":[],"command":{"binary":"gh","argv":["search","prs","--limit","100","--json","number,title,repository,author,state,createdAt,updatedAt","--","{{ args.query }}"]}},{"id":"gh.workflow_dispatch","title":"gh workflow run <workflow>","summary":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","description":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","kind":"exec","risk":"high","side_effects":["Workflow run begins.","Compute consumed.","Effects depend entirely on the workflow definition."],"args":[{"name":"workflow","type":"string","required":true,"description":"Workflow file basename (e.g., deploy.yml).","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"ref","type":"string","required":false,"default":"main","description":"Branch/tag/SHA.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}}],"examples":[{"title":"Trigger deploy.yml on main","args":{"workflow":"deploy.yml"}}],"search_terms":["trigger deploy","manual release"],"command":{"binary":"gh","argv":["workflow","run","{{ args.workflow }}","--ref","{{ args.ref }}"]}},{"id":"gh.workflow_list","title":"gh workflow list","summary":"List all workflows defined in one repo.","description":"List all workflows defined in one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Workflows","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["workflow","list","--repo","{{ args.repo }}","--all"]}},{"id":"gh.workflow_rerun","title":"gh run rerun <run-id>","summary":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","description":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","kind":"exec","risk":"medium","side_effects":["Workflow run starts again.","Compute consumed.","Notifications fire."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Workflow run ID.","validation":{"min":1,"max":99999999999}},{"name":"failed_only","type":"boolean","required":false,"default":true,"description":"Only re-run failed jobs."}],"examples":[{"title":"Re-run failed jobs only","args":{"run_id":12345678}}],"search_terms":["retry build","flaky failure"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.failed_only }}' = 'true' ]; then gh run rerun {{ args.run_id }} --failed; else gh run rerun {{ args.run_id }}; fi"]}},{"id":"gh.workflow_run_list","title":"gh run list","summary":"List recent workflow runs across the repo.","description":"List recent workflow runs across the repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max runs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Recent runs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":["recent builds"],"command":{"binary":"gh","argv":["run","list","--repo","{{ args.repo }}","--limit","{{ args.limit }}","--json","databaseId,name,conclusion,status,workflowName,event,headBranch,createdAt"]}},{"id":"gh.workflow_run_logs","title":"gh run view --log-failed","summary":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","description":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","kind":"exec","risk":"medium","side_effects":["Downloads logs.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID.","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"Failed-job logs","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":["ci broken","build failed","pipeline failure"],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--log-failed"]}},{"id":"gh.workflow_run_view","title":"gh run view","summary":"Show job-by-job result for one workflow run.","description":"Show job-by-job result for one workflow run.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID (databaseId from run list).","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"One run","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":[],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--json","name,conclusion,jobs,createdAt,updatedAt"]}}],"previous_versions":[{"version":"0.1.14","content_hash":"sha256:1d30b0fff49daeac77ebda650ca1ec19b0ba3b60ca3c702956fa25d4d27f5cf1","tarball_url":"https://registry.emisar.dev/v1/packs/github-cli/0.1.14/1d30b0fff49daeac77ebda650ca1ec19b0ba3b60ca3c702956fa25d4d27f5cf1/pack.tar.gz","actions":[{"id":"gh.auth_status","title":"gh auth status","summary":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","description":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","kind":"exec","risk":"low","side_effects":["One API call to /user.","Read-only."],"args":[],"examples":[{"title":"Who am I?","args":{}}],"search_terms":[],"command":{"binary":"gh","argv":["auth","status"]}},{"id":"gh.branch_list","title":"gh api repos/<repo>/branches","summary":"List branches in the repo (paginated, up to 100).","description":"List branches in the repo (paginated, up to 100).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Branches","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/branches?per_page=100"]}},{"id":"gh.issue_list","title":"gh issue list","summary":"List open issues for one repo.","description":"List open issues for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | all.","validation":{"enum":["open","closed","all"]}}],"examples":[{"title":"Open issues","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,labels,createdAt,updatedAt"]}},{"id":"gh.issue_view","title":"gh issue view","summary":"Show details + comments for one issue.","description":"Show details + comments for one issue.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"issue","type":"integer","required":true,"description":"Issue number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One issue","args":{"issue":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","view","{{ args.issue }}","--repo","{{ args.repo }}","--comments","--json","number,title,body,state,author,labels,comments,createdAt"]}},{"id":"gh.pr_checks","title":"gh pr checks","summary":"List all CI checks for one PR + pass/fail status.","description":"List all CI checks for one PR + pass/fail status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"PR checks","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":["checks red"],"command":{"binary":"gh","argv":["pr","checks","{{ args.pr }}","--repo","{{ args.repo }}"]}},{"id":"gh.pr_close","title":"gh pr close <num>","summary":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","description":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","kind":"exec","risk":"medium","side_effects":["PR state set to closed.","PR branch unchanged.","Notifications fire."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"Close a stale PR","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","close","{{ args.pr }}"]}},{"id":"gh.pr_list","title":"gh pr list","summary":"List open PRs for one repo.","description":"List open PRs for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | merged | all.","validation":{"enum":["open","closed","merged","all"]}}],"examples":[{"title":"Open PRs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,createdAt,updatedAt,mergeable,reviewDecision"]}},{"id":"gh.pr_merge","title":"gh pr merge <num> --<method>","summary":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","description":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","kind":"exec","risk":"high","side_effects":["PR merged into the base branch.","main/master CI pipeline likely triggers.","PR branch may be auto-deleted depending on repo settings."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}},{"name":"method","type":"string","required":false,"default":"squash","description":"Merge method.","validation":{"enum":["squash","merge","rebase"]}}],"examples":[{"title":"Squash-merge PR 1234","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","merge","{{ args.pr }}","--{{ args.method }}"]}},{"id":"gh.pr_view","title":"gh pr view","summary":"Show details for one PR — title, body, status, reviews, checks.","description":"Show details for one PR — title, body, status, reviews, checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One PR","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","view","{{ args.pr }}","--repo","{{ args.repo }}","--json","number,title,body,state,author,createdAt,mergedAt,reviewDecision,statusCheckRollup"]}},{"id":"gh.release_list","title":"gh release list","summary":"List recent releases.","description":"List recent releases.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Releases","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["release","list","--repo","{{ args.repo }}","--limit","20"]}},{"id":"gh.repo_clone_count","title":"gh api repos/<repo>/traffic/clones","summary":"Show last-14-day clone counts (requires push access on the repo).","description":"Show last-14-day clone counts (requires push access on the repo).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Clone traffic","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/traffic/clones"]}},{"id":"gh.repo_view","title":"gh repo view","summary":"Show repo summary — description, stars, default branch, latest release.","description":"Show repo summary — description, stars, default branch, latest release.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,39}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Repo summary","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["repo","view","{{ args.repo }}","--json","name,description,defaultBranchRef,stargazerCount,forkCount,latestRelease,isArchived,isPrivate"]}},{"id":"gh.search_prs","title":"gh search prs","summary":"Search PRs across all of GitHub by query.","description":"Search PRs across all of GitHub by query.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"GitHub search syntax (e.g. \"repo:owner/name author:foo state:open\").","validation":{"pattern":"^.{1,512}$"}}],"examples":[{"title":"My open PRs","args":{"query":"author:@me state:open"}}],"search_terms":[],"command":{"binary":"gh","argv":["search","prs","--limit","100","--json","number,title,repository,author,state,createdAt,updatedAt","--","{{ args.query }}"]}},{"id":"gh.workflow_dispatch","title":"gh workflow run <workflow>","summary":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","description":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","kind":"exec","risk":"high","side_effects":["Workflow run begins.","Compute consumed.","Effects depend entirely on the workflow definition."],"args":[{"name":"workflow","type":"string","required":true,"description":"Workflow file basename (e.g., deploy.yml).","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"ref","type":"string","required":false,"default":"main","description":"Branch/tag/SHA.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}}],"examples":[{"title":"Trigger deploy.yml on main","args":{"workflow":"deploy.yml"}}],"search_terms":["trigger deploy","manual release"],"command":{"binary":"gh","argv":["workflow","run","{{ args.workflow }}","--ref","{{ args.ref }}"]}},{"id":"gh.workflow_list","title":"gh workflow list","summary":"List all workflows defined in one repo.","description":"List all workflows defined in one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Workflows","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["workflow","list","--repo","{{ args.repo }}","--all"]}},{"id":"gh.workflow_rerun","title":"gh run rerun <run-id>","summary":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","description":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","kind":"exec","risk":"medium","side_effects":["Workflow run starts again.","Compute consumed.","Notifications fire."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Workflow run ID.","validation":{"min":1,"max":99999999999}},{"name":"failed_only","type":"boolean","required":false,"default":true,"description":"Only re-run failed jobs."}],"examples":[{"title":"Re-run failed jobs only","args":{"run_id":12345678}}],"search_terms":["retry build","flaky failure"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.failed_only }}' = 'true' ]; then gh run rerun {{ args.run_id }} --failed; else gh run rerun {{ args.run_id }}; fi"]}},{"id":"gh.workflow_run_list","title":"gh run list","summary":"List recent workflow runs across the repo.","description":"List recent workflow runs across the repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max runs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Recent runs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":["recent builds"],"command":{"binary":"gh","argv":["run","list","--repo","{{ args.repo }}","--limit","{{ args.limit }}","--json","databaseId,name,conclusion,status,workflowName,event,headBranch,createdAt"]}},{"id":"gh.workflow_run_logs","title":"gh run view --log-failed","summary":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","description":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","kind":"exec","risk":"low","side_effects":["Downloads logs.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID.","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"Failed-job logs","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":["ci broken","build failed","pipeline failure"],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--log-failed"]}},{"id":"gh.workflow_run_view","title":"gh run view","summary":"Show job-by-job result for one workflow run.","description":"Show job-by-job result for one workflow run.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID (databaseId from run list).","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"One run","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":[],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--json","name,conclusion,jobs,createdAt,updatedAt"]}}]},{"version":"0.1.9","content_hash":"sha256:35ca71f482e08b84a5e59fe3988bbf30f931260a98228a105bed3f6b5ca8048f","tarball_url":"https://registry.emisar.dev/v1/packs/github-cli/0.1.9/35ca71f482e08b84a5e59fe3988bbf30f931260a98228a105bed3f6b5ca8048f/pack.tar.gz","actions":[{"id":"gh.auth_status","title":"gh auth status","summary":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","description":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","kind":"exec","risk":"low","side_effects":["One API call to /user.","Read-only."],"args":[],"examples":[{"title":"Who am I?","args":{}}],"search_terms":[],"command":{"binary":"gh","argv":["auth","status"]}},{"id":"gh.branch_list","title":"gh api repos/<repo>/branches","summary":"List branches in the repo (paginated, up to 100).","description":"List branches in the repo (paginated, up to 100).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Branches","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/branches?per_page=100"]}},{"id":"gh.issue_list","title":"gh issue list","summary":"List open issues for one repo.","description":"List open issues for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | all.","validation":{"enum":["open","closed","all"]}}],"examples":[{"title":"Open issues","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,labels,createdAt,updatedAt"]}},{"id":"gh.issue_view","title":"gh issue view","summary":"Show details + comments for one issue.","description":"Show details + comments for one issue.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"issue","type":"integer","required":true,"description":"Issue number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One issue","args":{"issue":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","view","{{ args.issue }}","--repo","{{ args.repo }}","--comments","--json","number,title,body,state,author,labels,comments,createdAt"]}},{"id":"gh.pr_checks","title":"gh pr checks","summary":"List all CI checks for one PR + pass/fail status.","description":"List all CI checks for one PR + pass/fail status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"PR checks","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":["checks red"],"command":{"binary":"gh","argv":["pr","checks","{{ args.pr }}","--repo","{{ args.repo }}"]}},{"id":"gh.pr_close","title":"gh pr close <num>","summary":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","description":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","kind":"exec","risk":"medium","side_effects":["PR state set to closed.","PR branch unchanged.","Notifications fire."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"Close a stale PR","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","close","{{ args.pr }}"]}},{"id":"gh.pr_list","title":"gh pr list","summary":"List open PRs for one repo.","description":"List open PRs for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | merged | all.","validation":{"enum":["open","closed","merged","all"]}}],"examples":[{"title":"Open PRs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,createdAt,updatedAt,mergeable,reviewDecision"]}},{"id":"gh.pr_merge","title":"gh pr merge <num> --<method>","summary":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","description":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","kind":"exec","risk":"high","side_effects":["PR merged into the base branch.","main/master CI pipeline likely triggers.","PR branch may be auto-deleted depending on repo settings."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}},{"name":"method","type":"string","required":false,"default":"squash","description":"Merge method.","validation":{"enum":["squash","merge","rebase"]}}],"examples":[{"title":"Squash-merge PR 1234","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","merge","{{ args.pr }}","--{{ args.method }}"]}},{"id":"gh.pr_view","title":"gh pr view","summary":"Show details for one PR — title, body, status, reviews, checks.","description":"Show details for one PR — title, body, status, reviews, checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One PR","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","view","{{ args.pr }}","--repo","{{ args.repo }}","--json","number,title,body,state,author,createdAt,mergedAt,reviewDecision,statusCheckRollup"]}},{"id":"gh.release_list","title":"gh release list","summary":"List recent releases.","description":"List recent releases.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Releases","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["release","list","--repo","{{ args.repo }}","--limit","20"]}},{"id":"gh.repo_clone_count","title":"gh api repos/<repo>/traffic/clones","summary":"Show last-14-day clone counts (requires push access on the repo).","description":"Show last-14-day clone counts (requires push access on the repo).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Clone traffic","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/traffic/clones"]}},{"id":"gh.repo_view","title":"gh repo view","summary":"Show repo summary — description, stars, default branch, latest release.","description":"Show repo summary — description, stars, default branch, latest release.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,39}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Repo summary","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["repo","view","{{ args.repo }}","--json","name,description,defaultBranchRef,stargazerCount,forkCount,latestRelease,isArchived,isPrivate"]}},{"id":"gh.search_prs","title":"gh search prs","summary":"Search PRs across all of GitHub by query.","description":"Search PRs across all of GitHub by query.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"GitHub search syntax (e.g. \"repo:owner/name author:foo state:open\").","validation":{"pattern":"^.{1,512}$"}}],"examples":[{"title":"My open PRs","args":{"query":"author:@me state:open"}}],"search_terms":[],"command":{"binary":"gh","argv":["search","prs","--limit","100","--json","number,title,repository,author,state,createdAt,updatedAt","--","{{ args.query }}"]}},{"id":"gh.workflow_dispatch","title":"gh workflow run <workflow>","summary":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","description":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","kind":"exec","risk":"high","side_effects":["Workflow run begins.","Compute consumed.","Effects depend entirely on the workflow definition."],"args":[{"name":"workflow","type":"string","required":true,"description":"Workflow file basename (e.g., deploy.yml).","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"ref","type":"string","required":false,"default":"main","description":"Branch/tag/SHA.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}}],"examples":[{"title":"Trigger deploy.yml on main","args":{"workflow":"deploy.yml"}}],"search_terms":["trigger deploy","manual release"],"command":{"binary":"gh","argv":["workflow","run","{{ args.workflow }}","--ref","{{ args.ref }}"]}},{"id":"gh.workflow_list","title":"gh workflow list","summary":"List all workflows defined in one repo.","description":"List all workflows defined in one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Workflows","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["workflow","list","--repo","{{ args.repo }}","--all"]}},{"id":"gh.workflow_rerun","title":"gh run rerun <run-id>","summary":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","description":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","kind":"exec","risk":"medium","side_effects":["Workflow run starts again.","Compute consumed.","Notifications fire."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Workflow run ID.","validation":{"min":1,"max":99999999999}},{"name":"failed_only","type":"boolean","required":false,"default":true,"description":"Only re-run failed jobs."}],"examples":[{"title":"Re-run failed jobs only","args":{"run_id":12345678}}],"search_terms":["retry build","flaky failure"],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.failed_only }}' = 'true' ]; then gh run rerun {{ args.run_id }} --failed; else gh run rerun {{ args.run_id }}; fi"]}},{"id":"gh.workflow_run_list","title":"gh run list","summary":"List recent workflow runs across the repo.","description":"List recent workflow runs across the repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max runs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Recent runs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":["recent builds"],"command":{"binary":"gh","argv":["run","list","--repo","{{ args.repo }}","--limit","{{ args.limit }}","--json","databaseId,name,conclusion,status,workflowName,event,headBranch,createdAt"]}},{"id":"gh.workflow_run_logs","title":"gh run view --log-failed","summary":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","description":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","kind":"exec","risk":"low","side_effects":["Downloads logs.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID.","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"Failed-job logs","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":["ci broken","build failed","pipeline failure"],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--log-failed"]}},{"id":"gh.workflow_run_view","title":"gh run view","summary":"Show job-by-job result for one workflow run.","description":"Show job-by-job result for one workflow run.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID (databaseId from run list).","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"One run","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":[],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--json","name,conclusion,jobs,createdAt,updatedAt"]}}]},{"version":"0.1.8","content_hash":"sha256:a9e7697d78ec4ea3afcfadb99ee5619ff9d989f808b8bc8787a3757d0c4d6f48","tarball_url":"https://registry.emisar.dev/v1/packs/github-cli/0.1.8/a9e7697d78ec4ea3afcfadb99ee5619ff9d989f808b8bc8787a3757d0c4d6f48/pack.tar.gz","actions":[{"id":"gh.auth_status","title":"gh auth status","summary":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","description":"Show which GitHub account the runner's `gh` is signed in as + token scopes.","kind":"exec","risk":"low","side_effects":["One API call to /user.","Read-only."],"args":[],"examples":[{"title":"Who am I?","args":{}}],"search_terms":[],"command":{"binary":"gh","argv":["auth","status"]}},{"id":"gh.branch_list","title":"gh api repos/<repo>/branches","summary":"List branches in the repo (paginated, up to 100).","description":"List branches in the repo (paginated, up to 100).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Branches","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/branches?per_page=100"]}},{"id":"gh.issue_list","title":"gh issue list","summary":"List open issues for one repo.","description":"List open issues for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | all.","validation":{"enum":["open","closed","all"]}}],"examples":[{"title":"Open issues","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,labels,createdAt,updatedAt"]}},{"id":"gh.issue_view","title":"gh issue view","summary":"Show details + comments for one issue.","description":"Show details + comments for one issue.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"issue","type":"integer","required":true,"description":"Issue number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One issue","args":{"issue":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["issue","view","{{ args.issue }}","--repo","{{ args.repo }}","--comments","--json","number,title,body,state,author,labels,comments,createdAt"]}},{"id":"gh.pr_checks","title":"gh pr checks","summary":"List all CI checks for one PR + pass/fail status.","description":"List all CI checks for one PR + pass/fail status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"PR checks","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","checks","{{ args.pr }}","--repo","{{ args.repo }}"]}},{"id":"gh.pr_close","title":"gh pr close <num>","summary":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","description":"Close one PR without merging. Use for stale or abandoned PRs. Reopenable via the UI or `gh pr reopen`.","kind":"exec","risk":"medium","side_effects":["PR state set to closed.","PR branch unchanged.","Notifications fire."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"Close a stale PR","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","close","{{ args.pr }}"]}},{"id":"gh.pr_list","title":"gh pr list","summary":"List open PRs for one repo.","description":"List open PRs for one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"state","type":"string","required":false,"default":"open","description":"open | closed | merged | all.","validation":{"enum":["open","closed","merged","all"]}}],"examples":[{"title":"Open PRs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","list","--repo","{{ args.repo }}","--state","{{ args.state }}","--limit","100","--json","number,title,author,state,createdAt,updatedAt,mergeable,reviewDecision"]}},{"id":"gh.pr_merge","title":"gh pr merge <num> --<method>","summary":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","description":"Merge an open PR. Squash, merge-commit, or rebase. Branch protection rules still apply — required checks/approvals must be satisfied or the merge is rejected. Use --auto in the GH UI for \"merge when ready\" instead; this action commits NOW.","kind":"exec","risk":"high","side_effects":["PR merged into the base branch.","main/master CI pipeline likely triggers.","PR branch may be auto-deleted depending on repo settings."],"args":[{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}},{"name":"method","type":"string","required":false,"default":"squash","description":"Merge method.","validation":{"enum":["squash","merge","rebase"]}}],"examples":[{"title":"Squash-merge PR 1234","args":{"pr":1234}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","merge","{{ args.pr }}","--{{ args.method }}"]}},{"id":"gh.pr_view","title":"gh pr view","summary":"Show details for one PR — title, body, status, reviews, checks.","description":"Show details for one PR — title, body, status, reviews, checks.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"pr","type":"integer","required":true,"description":"PR number.","validation":{"min":1,"max":9999999}}],"examples":[{"title":"One PR","args":{"pr":1,"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["pr","view","{{ args.pr }}","--repo","{{ args.repo }}","--json","number,title,body,state,author,createdAt,mergedAt,reviewDecision,statusCheckRollup"]}},{"id":"gh.release_list","title":"gh release list","summary":"List recent releases.","description":"List recent releases.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Releases","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["release","list","--repo","{{ args.repo }}","--limit","20"]}},{"id":"gh.repo_clone_count","title":"gh api repos/<repo>/traffic/clones","summary":"Show last-14-day clone counts (requires push access on the repo).","description":"Show last-14-day clone counts (requires push access on the repo).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Clone traffic","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["api","repos/{{ args.repo }}/traffic/clones"]}},{"id":"gh.repo_view","title":"gh repo view","summary":"Show repo summary — description, stars, default branch, latest release.","description":"Show repo summary — description, stars, default branch, latest release.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,39}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Repo summary","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["repo","view","{{ args.repo }}","--json","name,description,defaultBranchRef,stargazerCount,forkCount,latestRelease,isArchived,isPrivate"]}},{"id":"gh.search_prs","title":"gh search prs","summary":"Search PRs across all of GitHub by query.","description":"Search PRs across all of GitHub by query.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"GitHub search syntax (e.g. \"repo:owner/name author:foo state:open\").","validation":{"pattern":"^.{1,512}$"}}],"examples":[{"title":"My open PRs","args":{"query":"author:@me state:open"}}],"search_terms":[],"command":{"binary":"gh","argv":["search","prs","--limit","100","--json","number,title,repository,author,state,createdAt,updatedAt","--","{{ args.query }}"]}},{"id":"gh.workflow_dispatch","title":"gh workflow run <workflow>","summary":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","description":"Trigger a workflow that supports workflow_dispatch. Pass ref + JSON inputs. Used for ad-hoc deploys, scripted rollbacks, or manual release flows.","kind":"exec","risk":"high","side_effects":["Workflow run begins.","Compute consumed.","Effects depend entirely on the workflow definition."],"args":[{"name":"workflow","type":"string","required":true,"description":"Workflow file basename (e.g., deploy.yml).","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"ref","type":"string","required":false,"default":"main","description":"Branch/tag/SHA.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}}],"examples":[{"title":"Trigger deploy.yml on main","args":{"workflow":"deploy.yml"}}],"search_terms":[],"command":{"binary":"gh","argv":["workflow","run","{{ args.workflow }}","--ref","{{ args.ref }}"]}},{"id":"gh.workflow_list","title":"gh workflow list","summary":"List all workflows defined in one repo.","description":"List all workflows defined in one repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}}],"examples":[{"title":"Workflows","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["workflow","list","--repo","{{ args.repo }}","--all"]}},{"id":"gh.workflow_rerun","title":"gh run rerun <run-id>","summary":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","description":"Re-run one workflow run. Useful after fixing a transient infrastructure issue. With --failed, only re-runs failed jobs.","kind":"exec","risk":"medium","side_effects":["Workflow run starts again.","Compute consumed.","Notifications fire."],"args":[{"name":"run_id","type":"integer","required":true,"description":"Workflow run ID.","validation":{"min":1,"max":99999999999}},{"name":"failed_only","type":"boolean","required":false,"default":true,"description":"Only re-run failed jobs."}],"examples":[{"title":"Re-run failed jobs only","args":{"run_id":12345678}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.failed_only }}' = 'true' ]; then gh run rerun {{ args.run_id }} --failed; else gh run rerun {{ args.run_id }}; fi"]}},{"id":"gh.workflow_run_list","title":"gh run list","summary":"List recent workflow runs across the repo.","description":"List recent workflow runs across the repo.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"limit","type":"integer","required":false,"default":50,"description":"Max runs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Recent runs","args":{"repo":"andrewdryga/emisar"}}],"search_terms":[],"command":{"binary":"gh","argv":["run","list","--repo","{{ args.repo }}","--limit","{{ args.limit }}","--json","databaseId,name,conclusion,status,workflowName,event,headBranch,createdAt"]}},{"id":"gh.workflow_run_logs","title":"gh run view --log-failed","summary":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","description":"Show logs from failed jobs in one run. Use for \"why did CI break?\".","kind":"exec","risk":"low","side_effects":["Downloads logs.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID.","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"Failed-job logs","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":[],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--log-failed"]}},{"id":"gh.workflow_run_view","title":"gh run view","summary":"Show job-by-job result for one workflow run.","description":"Show job-by-job result for one workflow run.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"repo","type":"string","required":true,"description":"Repo in owner/name form.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,40}/[a-zA-Z0-9_.\\-]{1,100}$"}},{"name":"run_id","type":"integer","required":true,"description":"Run ID (databaseId from run list).","validation":{"min":1,"max":999999999999}}],"examples":[{"title":"One run","args":{"repo":"andrewdryga/emisar","run_id":1234567890}}],"search_terms":[],"command":{"binary":"gh","argv":["run","view","{{ args.run_id }}","--repo","{{ args.repo }}","--json","name,conclusion,jobs,createdAt,updatedAt"]}}]}],"retired_below":"0.1.8"},{"id":"grafana","name":"Grafana","version":"0.1.16","description":"Grafana admin-API ops — datasource health, dashboard listings, alert state, user list, version, settings. Read-only. Auth via a bearer token or Basic credentials on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/grafana","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/grafana","content_hash":"sha256:84be5af9b08106a7eeb3de638150fa096b8987619973c977422bb9a9d41f50ba","tarball_url":"https://registry.emisar.dev/v1/packs/grafana/0.1.16/84be5af9b08106a7eeb3de638150fa096b8987619973c977422bb9a9d41f50ba/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["grafana-server","grafana"],"ports":[]},"setup":{"summary":"Every action calls the Grafana HTTP API at `$GRAFANA_URL` via curl. Set `$GRAFANA_TOKEN` for bearer authentication, or `$GRAFANA_USER` and `$GRAFANA_PASSWORD` for Basic authentication. Basic credentials are required for server-admin endpoints such as orgs and settings.","env":[{"name":"GRAFANA_URL","description":"Grafana base URL (scheme + host + port, no trailing path). Defaults to a local Grafana.","default":"http://127.0.0.1:3000","example":"https://grafana.internal:3000"},{"name":"GRAFANA_TOKEN","description":"Service-account token or API key sent as the Bearer credential."},{"name":"GRAFANA_USER","description":"Grafana user for Basic authentication. Takes precedence over `GRAFANA_TOKEN`.","example":"admin"},{"name":"GRAFANA_PASSWORD","description":"Password paired with `GRAFANA_USER`."}],"notes":["Any Grafana env var you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Create the token as a service account (Administration -> Service accounts) or a legacy API key; this pack is read-only, so a Viewer/Admin-read role is enough.","Server-admin endpoints do not accept service-account tokens; use a Grafana server-admin user's Basic credentials for orgs and settings."],"verify":"grafana.health"},"actions":[{"id":"grafana.alerting_rules","title":"GET /api/prometheus/grafana/api/v1/rules","summary":"List all Grafana-managed alert rules with last evaluation state.","description":"List all Grafana-managed alert rules with last evaluation state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Rules","args":{}}],"search_terms":[]},{"id":"grafana.alerting_state","title":"GET /api/alertmanager/grafana/api/v2/alerts","summary":"List currently-firing alerts known to Grafana's alertmanager.","description":"List currently-firing alerts known to Grafana's alertmanager.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Active alerts","args":{}}],"search_terms":[]},{"id":"grafana.dashboards_search","title":"GET /api/search","summary":"Search dashboards (default returns all dashboards).","description":"Search dashboards (default returns all dashboards).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"query","type":"string","required":false,"default":"","description":"Search string.","validation":{"pattern":"^[a-zA-Z0-9 _.\\-]{0,128}$"}}],"examples":[{"title":"All dashboards","args":{}}],"search_terms":[]},{"id":"grafana.datasource_health","title":"GET /api/datasources/uid/<uid>/health","summary":"Check health of one datasource (tests connectivity).","description":"Check health of one datasource (tests connectivity).","kind":"script","risk":"low","side_effects":["One API call that probes the downstream datasource.","Read-only."],"args":[{"name":"uid","type":"string","required":true,"description":"Datasource UID.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}}],"examples":[{"title":"Health","args":{"uid":"PBFA97CFB590B2093"}}],"search_terms":["datasource down","metrics missing","dashboards empty","no data"]},{"id":"grafana.datasources","title":"GET /api/datasources","summary":"List all datasources with type + URL + access mode.","description":"List all datasources with type + URL + access mode.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All datasources","args":{}}],"search_terms":[]},{"id":"grafana.health","title":"GET /api/health","summary":"Show liveness + DB-ok state.","description":"Show liveness + DB-ok state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Health","args":{}}],"search_terms":["grafana down"]},{"id":"grafana.orgs","title":"GET /api/orgs","summary":"List all orgs (multi-tenant view). Requires a Grafana server-admin token; an org-admin token gets 403 here (use grafana.users for the current org).","description":"List all orgs (multi-tenant view). Requires a Grafana server-admin token; an org-admin token gets 403 here (use grafana.users for the current org).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Orgs","args":{}}],"search_terms":[]},{"id":"grafana.settings","title":"GET /api/admin/settings","summary":"Show server settings (auth, smtp, database paths). Requires a Grafana server-admin token; an org-admin token gets 403 here. Grafana masks the credentials it recognizes and returns the rest as configured, so treat the response as secret-bearing.","description":"Show server settings (auth, smtp, database paths). Requires a Grafana server-admin token; an org-admin token gets 403 here. Grafana masks the credentials it recognizes and returns the rest as configured, so treat the response as secret-bearing.","kind":"script","risk":"high","side_effects":["One API call.","Read-only, but the response carries whatever credentials Grafana did not mask."],"args":[],"examples":[{"title":"Settings","args":{}}],"search_terms":[]},{"id":"grafana.users","title":"GET /api/org/users (org admin)","summary":"List all users in the current org. Requires an Admin-scoped token.","description":"List all users in the current org. Requires an Admin-scoped token.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Users","args":{}}],"search_terms":[]},{"id":"grafana.version","title":"GET /api/frontend/settings (build info)","summary":"Show build info, edition, license expiry.","description":"Show build info, edition, license expiry.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.14","content_hash":"sha256:63b0e0d337270390e92f432c9666a2312a27768194c1b68ffe41e7bc185190ba","tarball_url":"https://registry.emisar.dev/v1/packs/grafana/0.1.14/63b0e0d337270390e92f432c9666a2312a27768194c1b68ffe41e7bc185190ba/pack.tar.gz","actions":[{"id":"grafana.alerting_rules","title":"GET /api/prometheus/grafana/api/v1/rules","summary":"List all Grafana-managed alert rules with last evaluation state.","description":"List all Grafana-managed alert rules with last evaluation state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Rules","args":{}}],"search_terms":[]},{"id":"grafana.alerting_state","title":"GET /api/alertmanager/grafana/api/v2/alerts","summary":"List currently-firing alerts known to Grafana's alertmanager.","description":"List currently-firing alerts known to Grafana's alertmanager.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Active alerts","args":{}}],"search_terms":[]},{"id":"grafana.dashboards_search","title":"GET /api/search","summary":"Search dashboards (default returns all dashboards).","description":"Search dashboards (default returns all dashboards).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"query","type":"string","required":false,"default":"","description":"Search string.","validation":{"pattern":"^[a-zA-Z0-9 _.\\-]{0,128}$"}}],"examples":[{"title":"All dashboards","args":{}}],"search_terms":[]},{"id":"grafana.datasource_health","title":"GET /api/datasources/uid/<uid>/health","summary":"Check health of one datasource (tests connectivity).","description":"Check health of one datasource (tests connectivity).","kind":"script","risk":"low","side_effects":["One API call that probes the downstream datasource.","Read-only."],"args":[{"name":"uid","type":"string","required":true,"description":"Datasource UID.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}}],"examples":[{"title":"Health","args":{"uid":"PBFA97CFB590B2093"}}],"search_terms":["datasource down","metrics missing","dashboards empty","no data"]},{"id":"grafana.datasources","title":"GET /api/datasources","summary":"List all datasources with type + URL + access mode.","description":"List all datasources with type + URL + access mode.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"All datasources","args":{}}],"search_terms":[]},{"id":"grafana.health","title":"GET /api/health","summary":"Show liveness + DB-ok state.","description":"Show liveness + DB-ok state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Health","args":{}}],"search_terms":["grafana down"]},{"id":"grafana.orgs","title":"GET /api/orgs","summary":"List all orgs (multi-tenant view). Requires a Grafana server-admin token; an org-admin token gets 403 here (use grafana.users for the current org).","description":"List all orgs (multi-tenant view). Requires a Grafana server-admin token; an org-admin token gets 403 here (use grafana.users for the current org).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Orgs","args":{}}],"search_terms":[]},{"id":"grafana.settings","title":"GET /api/admin/settings","summary":"Show server settings (auth, smtp, database paths). Requires a Grafana server-admin token; an org-admin token gets 403 here. Grafana masks the credentials it recognizes and returns the rest as configured, so treat the response as secret-bearing.","description":"Show server settings (auth, smtp, database paths). Requires a Grafana server-admin token; an org-admin token gets 403 here. Grafana masks the credentials it recognizes and returns the rest as configured, so treat the response as secret-bearing.","kind":"script","risk":"high","side_effects":["One API call.","Read-only, but the response carries whatever credentials Grafana did not mask."],"args":[],"examples":[{"title":"Settings","args":{}}],"search_terms":[]},{"id":"grafana.users","title":"GET /api/org/users (org admin)","summary":"List all users in the current org. Requires an Admin-scoped token.","description":"List all users in the current org. Requires an Admin-scoped token.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Users","args":{}}],"search_terms":[]},{"id":"grafana.version","title":"GET /api/frontend/settings (build info)","summary":"Show build info, edition, license expiry.","description":"Show build info, edition, license expiry.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[]}]}],"retired_below":"0.1.14"},{"id":"haproxy","name":"HAProxy operations","version":"0.1.13","description":"Stats, server state, frontends/backends, session inventory, plus narrow mutators to enable/disable backend servers. Talks to the HAProxy admin socket. Set HAPROXY_SOCK env var on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/haproxy","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/haproxy","content_hash":"sha256:c658df4646525169e9837cf11b397104fd555855120bf5d98d8223b188df04fb","tarball_url":"https://registry.emisar.dev/v1/packs/haproxy/0.1.13/c658df4646525169e9837cf11b397104fd555855120bf5d98d8223b188df04fb/pack.tar.gz","requires":{"os":["linux"],"binaries":["socat"]},"detect":{"binaries":[],"processes":["haproxy"],"ports":[]},"setup":{"summary":"Talks to the local HAProxy admin/stats UNIX socket via socat on the runner host. There is no default — you must point `HAPROXY_SOCK` at the socket.","env":[{"name":"HAPROXY_SOCK","required":true,"description":"Path to the HAProxy admin/stats UNIX socket (the `stats socket` from haproxy.cfg).","example":"/run/haproxy/admin.sock"}],"notes":["`HAPROXY_SOCK` only reaches an action when the runner allowlists it in `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default. Unset, the actions fall back to the conventional socket path, so a non-default runtime socket reads the wrong one or is simply absent.","The socket must be declared with `level admin` in haproxy.cfg for the enable/disable/set mutators to work."],"host_access":[{"actions":["haproxy.show_info","haproxy.show_stat","haproxy.show_servers_state","haproxy.show_pools","haproxy.show_errors","haproxy.show_sess","haproxy.show_map","haproxy.show_backend","haproxy.show_frontend","haproxy.enable_server","haproxy.disable_server","haproxy.set_maxconn"],"requirement":"Read and write the configured HAProxy admin socket.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-haproxy-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. An HAProxy admin-level socket can change backend availability and runtime limits beyond the actions in this pack."}]}],"verify":"haproxy.show_info"},"actions":[{"id":"haproxy.disable_server","title":"disable server <backend>/<server>","summary":"Stop sending new traffic to one backend server (in-flight requests continue).","description":"Stop sending new traffic to one backend server (in-flight requests continue).","kind":"exec","risk":"high","side_effects":["Server is marked MAINT — no new traffic.","Existing requests finish."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Drain api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["drain","maintenance mode","out of rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'disable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.enable_server","title":"enable server <backend>/<server>","summary":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","description":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","kind":"exec","risk":"high","side_effects":["Server begins receiving traffic again (subject to health checks)."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Enable api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["back into rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'enable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.set_maxconn","title":"set maxconn frontend <name> <N>","summary":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","description":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","kind":"exec","risk":"high","side_effects":["Lowering below current conns rejects new connections until count drops."],"args":[{"name":"frontend","type":"string","required":true,"description":"Frontend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"maxconn","type":"integer","required":true,"description":"New cap.","validation":{"min":1,"max":1000000}}],"examples":[{"title":"Cap to 5000","args":{"frontend":"https-in","maxconn":5000}}],"search_terms":["connection limit"],"command":{"binary":"/bin/sh","argv":["-c","echo 'set maxconn frontend '\"$1\"' {{ args.maxconn }}' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.frontend }}"]}},{"id":"haproxy.show_backend","title":"show backend","summary":"List backend names.","description":"List backend names.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Backends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show backend' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_errors","title":"show errors","summary":"List recent request/response errors captured by HAProxy. Use to debug 503s.","description":"List recent request/response errors captured by HAProxy. Use to debug 503s.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show errors' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_frontend","title":"Frontend stats (show stat, type=frontend)","summary":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","description":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Frontends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat -1 1 -1' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_info","title":"show info","summary":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","description":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show info' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_map","title":"show map","summary":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","description":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Maps","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show map' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_pools","title":"show pools","summary":"Show internal memory pool usage. Use to spot leaks.","description":"Show internal memory pool usage. Use to spot leaks.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show pools' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_servers_state","title":"show servers state","summary":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","description":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Server state","args":{}}],"search_terms":["dead backend","backend down","unhealthy"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show servers state' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_sess","title":"show sess","summary":"List in-flight sessions (one row per active connection).","description":"List in-flight sessions (one row per active connection).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show sess' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_stat","title":"show stat","summary":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","description":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":["backend health"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat' | socat - \"$HAPROXY_SOCK\""]}}],"previous_versions":[{"version":"0.1.12","content_hash":"sha256:8fee8a22d598ae336c0c93f91436784d5595b0530040c0780f9d29a5740db984","tarball_url":"https://registry.emisar.dev/v1/packs/haproxy/0.1.12/8fee8a22d598ae336c0c93f91436784d5595b0530040c0780f9d29a5740db984/pack.tar.gz","actions":[{"id":"haproxy.disable_server","title":"disable server <backend>/<server>","summary":"Stop sending new traffic to one backend server (in-flight requests continue).","description":"Stop sending new traffic to one backend server (in-flight requests continue).","kind":"exec","risk":"high","side_effects":["Server is marked MAINT — no new traffic.","Existing requests finish."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Drain api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["drain","maintenance mode","out of rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'disable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.enable_server","title":"enable server <backend>/<server>","summary":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","description":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","kind":"exec","risk":"high","side_effects":["Server begins receiving traffic again (subject to health checks)."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Enable api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["back into rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'enable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.set_maxconn","title":"set maxconn frontend <name> <N>","summary":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","description":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","kind":"exec","risk":"high","side_effects":["Lowering below current conns rejects new connections until count drops."],"args":[{"name":"frontend","type":"string","required":true,"description":"Frontend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"maxconn","type":"integer","required":true,"description":"New cap.","validation":{"min":1,"max":1000000}}],"examples":[{"title":"Cap to 5000","args":{"frontend":"https-in","maxconn":5000}}],"search_terms":["connection limit"],"command":{"binary":"/bin/sh","argv":["-c","echo 'set maxconn frontend '\"$1\"' {{ args.maxconn }}' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.frontend }}"]}},{"id":"haproxy.show_backend","title":"show backend","summary":"List backend names.","description":"List backend names.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Backends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show backend' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_errors","title":"show errors","summary":"List recent request/response errors captured by HAProxy. Use to debug 503s.","description":"List recent request/response errors captured by HAProxy. Use to debug 503s.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show errors' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_frontend","title":"Frontend stats (show stat, type=frontend)","summary":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","description":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Frontends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat -1 1 -1' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_info","title":"show info","summary":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","description":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show info' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_map","title":"show map","summary":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","description":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Maps","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show map' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_pools","title":"show pools","summary":"Show internal memory pool usage. Use to spot leaks.","description":"Show internal memory pool usage. Use to spot leaks.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show pools' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_servers_state","title":"show servers state","summary":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","description":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Server state","args":{}}],"search_terms":["dead backend","backend down","unhealthy"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show servers state' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_sess","title":"show sess","summary":"List in-flight sessions (one row per active connection).","description":"List in-flight sessions (one row per active connection).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show sess' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_stat","title":"show stat","summary":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","description":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":["backend health"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat' | socat - \"$HAPROXY_SOCK\""]}}]},{"version":"0.1.10","content_hash":"sha256:ec8adf238fe457c31dfa8daadb88866bc7da0bc2b4290a6bbf4822acee362341","tarball_url":"https://registry.emisar.dev/v1/packs/haproxy/0.1.10/ec8adf238fe457c31dfa8daadb88866bc7da0bc2b4290a6bbf4822acee362341/pack.tar.gz","actions":[{"id":"haproxy.disable_server","title":"disable server <backend>/<server>","summary":"Stop sending new traffic to one backend server (in-flight requests continue).","description":"Stop sending new traffic to one backend server (in-flight requests continue).","kind":"exec","risk":"high","side_effects":["Server is marked MAINT — no new traffic.","Existing requests finish."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Drain api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["drain","maintenance mode","out of rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'disable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.enable_server","title":"enable server <backend>/<server>","summary":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","description":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","kind":"exec","risk":"high","side_effects":["Server begins receiving traffic again (subject to health checks)."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Enable api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["back into rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'enable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.set_maxconn","title":"set maxconn frontend <name> <N>","summary":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","description":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","kind":"exec","risk":"high","side_effects":["Lowering below current conns rejects new connections until count drops."],"args":[{"name":"frontend","type":"string","required":true,"description":"Frontend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"maxconn","type":"integer","required":true,"description":"New cap.","validation":{"min":1,"max":1000000}}],"examples":[{"title":"Cap to 5000","args":{"frontend":"https-in","maxconn":5000}}],"search_terms":["connection limit"],"command":{"binary":"/bin/sh","argv":["-c","echo 'set maxconn frontend '\"$1\"' {{ args.maxconn }}' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.frontend }}"]}},{"id":"haproxy.show_backend","title":"show backend","summary":"List backend names.","description":"List backend names.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Backends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show backend' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_errors","title":"show errors","summary":"List recent request/response errors captured by HAProxy. Use to debug 503s.","description":"List recent request/response errors captured by HAProxy. Use to debug 503s.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show errors' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_frontend","title":"Frontend stats (show stat, type=frontend)","summary":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","description":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Frontends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat -1 1 -1' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_info","title":"show info","summary":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","description":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show info' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_map","title":"show map","summary":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","description":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Maps","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show map' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_pools","title":"show pools","summary":"Show internal memory pool usage. Use to spot leaks.","description":"Show internal memory pool usage. Use to spot leaks.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show pools' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_servers_state","title":"show servers state","summary":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","description":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Server state","args":{}}],"search_terms":["dead backend","backend down","unhealthy"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show servers state' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_sess","title":"show sess","summary":"List in-flight sessions (one row per active connection).","description":"List in-flight sessions (one row per active connection).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show sess' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_stat","title":"show stat","summary":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","description":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":["backend health"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat' | socat - \"$HAPROXY_SOCK\""]}}]},{"version":"0.1.9","content_hash":"sha256:e6f230e3ecca80f4e3a5f9b79247978c0de792b02212a4e1ad46da8f1b4e7950","tarball_url":"https://registry.emisar.dev/v1/packs/haproxy/0.1.9/e6f230e3ecca80f4e3a5f9b79247978c0de792b02212a4e1ad46da8f1b4e7950/pack.tar.gz","actions":[{"id":"haproxy.disable_server","title":"disable server <backend>/<server>","summary":"Stop sending new traffic to one backend server (in-flight requests continue).","description":"Stop sending new traffic to one backend server (in-flight requests continue).","kind":"exec","risk":"high","side_effects":["Server is marked MAINT — no new traffic.","Existing requests finish."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Drain api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["drain","maintenance mode","out of rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'disable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.enable_server","title":"enable server <backend>/<server>","summary":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","description":"Re-enable one backend server that was administratively disabled; it returns to rotation and live traffic reaches it again (subject to health checks).","kind":"exec","risk":"high","side_effects":["Server begins receiving traffic again (subject to health checks)."],"args":[{"name":"backend","type":"string","required":true,"description":"Backend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"server","type":"string","required":true,"description":"Server name within the backend.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Enable api/srv1","args":{"backend":"api","server":"srv1"}}],"search_terms":["back into rotation"],"command":{"binary":"/bin/sh","argv":["-c","echo 'enable server '\"$1\"'/'\"$2\"'' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.backend }}","{{ args.server }}"]}},{"id":"haproxy.set_maxconn","title":"set maxconn frontend <name> <N>","summary":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","description":"Live-update the maxconn cap on one frontend without a reload; lowering it below the current connection count turns away new connections until the count drops.","kind":"exec","risk":"high","side_effects":["Lowering below current conns rejects new connections until count drops."],"args":[{"name":"frontend","type":"string","required":true,"description":"Frontend name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}},{"name":"maxconn","type":"integer","required":true,"description":"New cap.","validation":{"min":1,"max":1000000}}],"examples":[{"title":"Cap to 5000","args":{"frontend":"https-in","maxconn":5000}}],"search_terms":["connection limit"],"command":{"binary":"/bin/sh","argv":["-c","echo 'set maxconn frontend '\"$1\"' {{ args.maxconn }}' | socat - \"$HAPROXY_SOCK\"","emisar","{{ args.frontend }}"]}},{"id":"haproxy.show_backend","title":"show backend","summary":"List backend names.","description":"List backend names.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Backends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show backend' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_errors","title":"show errors","summary":"List recent request/response errors captured by HAProxy. Use to debug 503s.","description":"List recent request/response errors captured by HAProxy. Use to debug 503s.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show errors' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_frontend","title":"Frontend stats (show stat, type=frontend)","summary":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","description":"Show per-frontend stats (status, sessions, bytes, denied, errors) as CSV. There is no `show frontend` Runtime-API command, so this uses `show stat -1 1 -1` — the stat dump filtered to type=frontend (the bitmask 1 = frontend).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Frontends","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat -1 1 -1' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_info","title":"show info","summary":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","description":"Show HAProxy version, uptime, process stats, conn rate, mem usage.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show info' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_map","title":"show map","summary":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","description":"List all loaded `map` files (the lookup tables HAProxy uses for routing).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Maps","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show map' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_pools","title":"show pools","summary":"Show internal memory pool usage. Use to spot leaks.","description":"Show internal memory pool usage. Use to spot leaks.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show pools' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_servers_state","title":"show servers state","summary":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","description":"Show persisted server state — health, weight, admin overrides. Read this before reloading config to know what state should be preserved.","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Server state","args":{}}],"search_terms":["dead backend","backend down","unhealthy"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show servers state' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_sess","title":"show sess","summary":"List in-flight sessions (one row per active connection).","description":"List in-flight sessions (one row per active connection).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Sessions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","echo 'show sess' | socat - \"$HAPROXY_SOCK\""]}},{"id":"haproxy.show_stat","title":"show stat","summary":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","description":"Show per-proxy + per-server stats (sessions, queues, bytes, errors, response times).","kind":"exec","risk":"low","side_effects":["One admin socket command.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":["backend health"],"command":{"binary":"/bin/sh","argv":["-c","echo 'show stat' | socat - \"$HAPROXY_SOCK\""]}}]}]},{"id":"hcp-terraform","name":"HCP Terraform run review and gating","version":"0.8.5","description":"Review HCP Terraform (formerly Terraform Cloud) and Terraform Enterprise runs and gate what happens next: list workspaces and runs, project a run's plan into a summary that carries no resource or output values but does identify the bounded attribute paths that force replacement, read why a run failed from a bounded tail of its plan or apply log, queue a speculative plan-only run, retry a failed run against its exact configuration version, and confirm, discard, or cancel a run through emisar's policy and approval path instead of the HCP UI.","vendor":"emisar","homepage":"https://emisar.dev/packs/hcp-terraform","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/hcp-terraform","content_hash":"sha256:cd42867c0e8237d86308dd01b99b9bd9db46a1134aa1a7b20b18f952c0667766","tarball_url":"https://registry.emisar.dev/v1/packs/hcp-terraform/0.8.5/cd42867c0e8237d86308dd01b99b9bd9db46a1134aa1a7b20b18f952c0667766/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Calls the HCP Terraform JSON:API over HTTPS with curl, sending the token in an Authorization: Bearer header read from `TFE_TOKEN`, so allowlist that variable in `inherit_env`. Point `TFE_ADDRESS` at your Terraform Enterprise host to use this against a self-managed install.","env":[{"name":"TFE_TOKEN","required":true,"description":"API token. A user or team token scoped to the workspaces you want reviewable; see the notes for what each action needs."},{"name":"TFE_ADDRESS","description":"API host, for Terraform Enterprise or a private HCP region.","default":"https://app.terraform.io","example":"https://tfe.example.com"}],"notes":["Create a user token at [app.terraform.io/app/settings/tokens](https://app.terraform.io/app/settings/tokens), or a team token under Organization Settings → Teams → the team → Team API token. The organization token (Organization Settings → API tokens) is the one several actions here reject.","plan_summary calls the plan's json-output endpoint, which HashiCorp does NOT allow organization tokens to reach: it needs a user or team token with admin access to the workspace. run_details works with any token that can read runs and still reports the plan's add/change/destroy counts, so prefer it when you do not want to hand out workspace admin.","apply_run, discard_run, and cancel_run also reject organization tokens — HCP requires a user or team token with permission to apply runs for the workspace.","The token can do everything these actions expose, so scope it to the workspaces you actually want reachable and let emisar policy decide who may reach the mutating actions.","Needs curl 7.76 or newer: the actions use --fail-with-body so a rejected request reports the API's error document instead of failing with empty output.","json-output answers with a one-minute presigned redirect. curl drops the Authorization header on that cross-host hop by design; the redirect target carries its own signature.","run_diagnostics downloads the failed phase's log through the presigned URL HCP returns. That URL is a credential and never appears in output or audit, but the log text itself becomes part of the governed result — which is why this read is medium risk and policy-gated.","retry_run creates a standard run, so HCP requires a user or team token that can queue plans in the workspace. The new run is created with auto-apply off and still needs tfc.apply_run before anything changes."],"verify":"tfc.list_organizations"},"actions":[{"id":"tfc.apply_run","title":"POST /runs/<id>/actions/apply","summary":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","description":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","kind":"script","risk":"high","side_effects":["Applies the plan — creates, modifies, and destroys real infrastructure.","Cannot be reversed; a mistaken apply needs a corrective run.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to confirm (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Confirm a reviewed run","args":{"comment":"Reviewed via emisar","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.cancel_run","title":"POST /runs/<id>/actions/cancel","summary":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","description":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Interrupts the run; an apply already in flight stops partway through.","Can leave infrastructure partially changed and state needing reconciliation.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to cancel (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Interrupt a stuck run","args":{"comment":"Interrupting a hung plan","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.create_plan_only_run","title":"POST /runs (plan-only)","summary":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","description":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates no applyable plan; a plan-only run cannot be confirmed."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to plan against (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Ask what a workspace would change","args":{"message":"Pre-change review","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["what would change","speculative plan","dry run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.discard_run","title":"POST /runs/<id>/actions/discard","summary":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","description":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Abandons the pending plan; it can never be applied afterwards.","Unlocks the workspace, letting a queued run proceed.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to discard (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Discard a plan that should not ship","args":{"comment":"Superseded","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.force_unlock_workspace","title":"POST /workspaces/<id>/actions/force-unlock","summary":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team.","description":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team. This is the recovery for a dead run that never released its lock — but if that run is in fact still applying, breaking the lock lets a second writer at the state and can corrupt or lose it. First read the holder from tfc.workspace_details and confirm with tfc.run_details that it is finished, and when a plain unlock answers 503 (state still finalizing), retry tfc.unlock_workspace instead of escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"high","side_effects":["Breaks any lock, including a live run's — an apply still writing then shares state with the next writer, which can corrupt or lose state.","Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Requires a user or team token with admin access to the workspace."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to force-unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"Break a dead run's lock","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["force unlock a stuck workspace","lock held by a dead run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.list_organizations","title":"GET /organizations","summary":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","description":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":20,"description":"Organizations per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Organizations this token can reach","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"organizations":{"items":{"additionalProperties":false,"properties":{"created_at":{"type":"string"},"email":{"maxLength":100,"type":"string"},"name":{"type":"string"}},"required":["name","email","created_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["organizations","next_page"],"type":"object"}},{"id":"tfc.list_runs","title":"GET /workspaces/<id>/runs","summary":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","description":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace ID from list_workspaces (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Runs per page.","validation":{"min":1,"max":12}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent runs in a workspace","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["run waiting for approval","pending apply","stuck run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"maxItems":12,"type":"array"}},"required":["runs","next_page"],"type":"object"}},{"id":"tfc.list_workspaces","title":"GET /organizations/<name>/workspaces","summary":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","description":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"page_size","type":"integer","required":false,"default":20,"description":"Workspaces per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Workspaces in an organization","args":{"organization":"example-corp"}}],"search_terms":["which workspaces auto-apply","locked workspace"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"workspaces":{"items":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","resource_count","updated_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["workspaces","next_page"],"type":"object"}},{"id":"tfc.lock_workspace","title":"POST /workspaces/<id>/actions/lock","summary":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","description":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["New and queued runs hold before planning or applying until the workspace is unlocked.","Blocks state writes; reversible with tfc.unlock_workspace.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to lock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"reason","type":"string","required":false,"default":"","description":"Reason recorded on the lock in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Freeze a workspace during an investigation","args":{"reason":"Incident 4821 investigation","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["freeze a workspace","maintenance lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.plan_summary","title":"Project an HCP Terraform plan into a reviewable summary","summary":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes.","description":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, names, and the bounded `replace_paths` that identify replacement-forcing attributes — because the structured plan HCP Terraform serves carries every value in cleartext, sensitive ones included. Needs a user or team token with admin access to the workspace; tfc.run_details gives counts on a read-only token.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET, followed to the API's presigned redirect.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Review what a run would change","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["review plan","what will change","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"replace_paths":{"items":{"maxLength":32,"type":"string"},"maxItems":2,"type":"array"},"replace_paths_truncated":{"minimum":0,"type":"integer"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason","replace_paths","replace_paths_truncated"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"hcp_plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","truncated"],"type":"object"}},{"id":"tfc.retry_run","title":"POST /runs (retry a failed run's exact configuration)","summary":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version.","description":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version. Only an errored, canceled, force-canceled, or discarded source can be retried, and both IDs are taken from the fetched source run, never from the caller. The new run is created with plan-only and auto-apply explicitly false, so nothing is applied until a human confirms it through tfc.apply_run. Only the configuration is pinned: workspace variables and provider state are re-read when the new run plans.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates a confirmable run; applying it still requires tfc.apply_run."],"args":[{"name":"source_run_id","type":"string","required":true,"description":"Errored, canceled, force-canceled, or discarded run to retry (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the new run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Retry an errored run unchanged","args":{"message":"Retry after fixing provider credentials","source_run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["retry failed run","re-run terraform","rerun errored run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"configuration_version_id":{"type":"string"},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"source_run_id":{"type":"string"}},"required":["run","source_run_id","configuration_version_id"],"type":"object"}},{"id":"tfc.run_details","title":"GET /runs/<id>?include=plan","summary":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","description":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"One run and its plan counts","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["how many resources will be destroyed","blast radius"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"plan":{"additionalProperties":false,"properties":{"has_changes":{"type":"boolean"},"id":{"type":"string"},"resource_additions":{"type":"integer"},"resource_changes":{"type":"integer"},"resource_destructions":{"type":"integer"},"resource_imports":{"type":"integer"},"status":{"type":"string"}},"required":["id","status","has_changes","resource_additions","resource_changes","resource_destructions","resource_imports"],"type":["object","null"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","plan"],"type":"object"}},{"id":"tfc.run_diagnostics","title":"Diagnose a failed run from its plan or apply log","summary":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped.","description":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped. Provider logs can carry sensitive operational values, so this read is medium risk and policy-gated even though it changes nothing. The presigned log URL HCP returns is fetched but never emitted, and a missing or unreadable log is reported explicitly instead of passing as an empty tail.","kind":"script","risk":"medium","side_effects":["Two read-only HTTP GETs — the run, then its phase's presigned log URL.","Emits provider log content, which can include sensitive operational values.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Errored or canceled run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Read why a run errored","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["why did the run fail","errored run","terraform apply error log","diagnose failed run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"diagnostics":{"additionalProperties":false,"properties":{"ended_at":{"type":"string"},"started_at":{"type":"string"},"status":{"type":"string"}},"required":["status","started_at","ended_at"],"type":"object"},"log":{"additionalProperties":false,"properties":{"available":{"type":"boolean"},"reason":{"type":"string"},"tail":{"items":{"maxLength":2048,"type":"string"},"maxItems":60,"type":"array"}},"required":["available"],"type":"object"},"phase":{"enum":["plan","apply"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","phase","diagnostics","log"],"type":"object"}},{"id":"tfc.unlock_workspace","title":"POST /workspaces/<id>/actions/unlock","summary":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","description":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Cannot release a lock held by a run or a different user; that answers 409.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"End a maintenance freeze","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["unfreeze a workspace","release the workspace lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.workspace_details","title":"GET /organizations/<name>/workspaces/<workspace>","summary":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","description":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"workspace","type":"string","required":true,"description":"Workspace name, as shown in HCP Terraform.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,89}$","max_length":90}}],"examples":[{"title":"Why is production-network locked","args":{"organization":"example-corp","workspace":"production-network"}}],"search_terms":["who locked this workspace","workspace lock holder"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}}],"previous_versions":[{"version":"0.8.4","content_hash":"sha256:584906efff650fff284488d30b558a37fa0c921a0accda74f499de023941c067","tarball_url":"https://registry.emisar.dev/v1/packs/hcp-terraform/0.8.4/584906efff650fff284488d30b558a37fa0c921a0accda74f499de023941c067/pack.tar.gz","actions":[{"id":"tfc.apply_run","title":"POST /runs/<id>/actions/apply","summary":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","description":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","kind":"script","risk":"high","side_effects":["Applies the plan — creates, modifies, and destroys real infrastructure.","Cannot be reversed; a mistaken apply needs a corrective run.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to confirm (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Confirm a reviewed run","args":{"comment":"Reviewed via emisar","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.cancel_run","title":"POST /runs/<id>/actions/cancel","summary":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","description":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Interrupts the run; an apply already in flight stops partway through.","Can leave infrastructure partially changed and state needing reconciliation.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to cancel (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Interrupt a stuck run","args":{"comment":"Interrupting a hung plan","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.create_plan_only_run","title":"POST /runs (plan-only)","summary":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","description":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates no applyable plan; a plan-only run cannot be confirmed."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to plan against (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Ask what a workspace would change","args":{"message":"Pre-change review","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["what would change","speculative plan","dry run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.discard_run","title":"POST /runs/<id>/actions/discard","summary":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","description":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Abandons the pending plan; it can never be applied afterwards.","Unlocks the workspace, letting a queued run proceed.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to discard (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Discard a plan that should not ship","args":{"comment":"Superseded","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.force_unlock_workspace","title":"POST /workspaces/<id>/actions/force-unlock","summary":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team.","description":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team. This is the recovery for a dead run that never released its lock — but if that run is in fact still applying, breaking the lock lets a second writer at the state and can corrupt or lose it. First read the holder from tfc.workspace_details and confirm with tfc.run_details that it is finished, and when a plain unlock answers 503 (state still finalizing), retry tfc.unlock_workspace instead of escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"high","side_effects":["Breaks any lock, including a live run's — an apply still writing then shares state with the next writer, which can corrupt or lose state.","Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Requires a user or team token with admin access to the workspace."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to force-unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"Break a dead run's lock","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["force unlock a stuck workspace","lock held by a dead run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.list_organizations","title":"GET /organizations","summary":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","description":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":20,"description":"Organizations per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Organizations this token can reach","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"organizations":{"items":{"additionalProperties":false,"properties":{"created_at":{"type":"string"},"email":{"maxLength":100,"type":"string"},"name":{"type":"string"}},"required":["name","email","created_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["organizations","next_page"],"type":"object"}},{"id":"tfc.list_runs","title":"GET /workspaces/<id>/runs","summary":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","description":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace ID from list_workspaces (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Runs per page.","validation":{"min":1,"max":12}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent runs in a workspace","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["run waiting for approval","pending apply","stuck run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"maxItems":12,"type":"array"}},"required":["runs","next_page"],"type":"object"}},{"id":"tfc.list_workspaces","title":"GET /organizations/<name>/workspaces","summary":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","description":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"page_size","type":"integer","required":false,"default":20,"description":"Workspaces per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Workspaces in an organization","args":{"organization":"example-corp"}}],"search_terms":["which workspaces auto-apply","locked workspace"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"workspaces":{"items":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","resource_count","updated_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["workspaces","next_page"],"type":"object"}},{"id":"tfc.lock_workspace","title":"POST /workspaces/<id>/actions/lock","summary":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","description":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["New and queued runs hold before planning or applying until the workspace is unlocked.","Blocks state writes; reversible with tfc.unlock_workspace.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to lock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"reason","type":"string","required":false,"default":"","description":"Reason recorded on the lock in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Freeze a workspace during an investigation","args":{"reason":"Incident 4821 investigation","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["freeze a workspace","maintenance lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.plan_summary","title":"Project an HCP Terraform plan into a reviewable summary","summary":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes.","description":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, names, and the bounded `replace_paths` that identify replacement-forcing attributes — because the structured plan HCP Terraform serves carries every value in cleartext, sensitive ones included. Needs a user or team token with admin access to the workspace; tfc.run_details gives counts on a read-only token.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET, followed to the API's presigned redirect.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Review what a run would change","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["review plan","what will change","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"replace_paths":{"items":{"maxLength":32,"type":"string"},"maxItems":2,"type":"array"},"replace_paths_truncated":{"minimum":0,"type":"integer"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason","replace_paths","replace_paths_truncated"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"hcp_plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","truncated"],"type":"object"}},{"id":"tfc.retry_run","title":"POST /runs (retry a failed run's exact configuration)","summary":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version.","description":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version. Only an errored, canceled, force-canceled, or discarded source can be retried, and both IDs are taken from the fetched source run, never from the caller. The new run is created with plan-only and auto-apply explicitly false, so nothing is applied until a human confirms it through tfc.apply_run. Only the configuration is pinned: workspace variables and provider state are re-read when the new run plans.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates a confirmable run; applying it still requires tfc.apply_run."],"args":[{"name":"source_run_id","type":"string","required":true,"description":"Errored, canceled, force-canceled, or discarded run to retry (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the new run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Retry an errored run unchanged","args":{"message":"Retry after fixing provider credentials","source_run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["retry failed run","re-run terraform","rerun errored run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"configuration_version_id":{"type":"string"},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"source_run_id":{"type":"string"}},"required":["run","source_run_id","configuration_version_id"],"type":"object"}},{"id":"tfc.run_details","title":"GET /runs/<id>?include=plan","summary":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","description":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"One run and its plan counts","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["how many resources will be destroyed","blast radius"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"plan":{"additionalProperties":false,"properties":{"has_changes":{"type":"boolean"},"id":{"type":"string"},"resource_additions":{"type":"integer"},"resource_changes":{"type":"integer"},"resource_destructions":{"type":"integer"},"resource_imports":{"type":"integer"},"status":{"type":"string"}},"required":["id","status","has_changes","resource_additions","resource_changes","resource_destructions","resource_imports"],"type":["object","null"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","plan"],"type":"object"}},{"id":"tfc.run_diagnostics","title":"Diagnose a failed run from its plan or apply log","summary":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped.","description":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped. Provider logs can carry sensitive operational values, so this read is medium risk and policy-gated even though it changes nothing. The presigned log URL HCP returns is fetched but never emitted, and a missing or unreadable log is reported explicitly instead of passing as an empty tail.","kind":"script","risk":"medium","side_effects":["Two read-only HTTP GETs — the run, then its phase's presigned log URL.","Emits provider log content, which can include sensitive operational values.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Errored or canceled run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Read why a run errored","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["why did the run fail","errored run","terraform apply error log","diagnose failed run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"diagnostics":{"additionalProperties":false,"properties":{"ended_at":{"type":"string"},"started_at":{"type":"string"},"status":{"type":"string"}},"required":["status","started_at","ended_at"],"type":"object"},"log":{"additionalProperties":false,"properties":{"available":{"type":"boolean"},"reason":{"type":"string"},"tail":{"items":{"maxLength":2048,"type":"string"},"maxItems":60,"type":"array"}},"required":["available"],"type":"object"},"phase":{"enum":["plan","apply"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","phase","diagnostics","log"],"type":"object"}},{"id":"tfc.unlock_workspace","title":"POST /workspaces/<id>/actions/unlock","summary":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","description":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Cannot release a lock held by a run or a different user; that answers 409.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"End a maintenance freeze","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["unfreeze a workspace","release the workspace lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.workspace_details","title":"GET /organizations/<name>/workspaces/<workspace>","summary":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","description":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"workspace","type":"string","required":true,"description":"Workspace name, as shown in HCP Terraform.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,89}$","max_length":90}}],"examples":[{"title":"Why is production-network locked","args":{"organization":"example-corp","workspace":"production-network"}}],"search_terms":["who locked this workspace","workspace lock holder"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}}]},{"version":"0.8.0","content_hash":"sha256:5d753dced1595977ce9ec640dea0b26057ce95d38a6dfbcc27b3a0f4e4fc2592","tarball_url":"https://registry.emisar.dev/v1/packs/hcp-terraform/0.8.0/5d753dced1595977ce9ec640dea0b26057ce95d38a6dfbcc27b3a0f4e4fc2592/pack.tar.gz","actions":[{"id":"tfc.apply_run","title":"POST /runs/<id>/actions/apply","summary":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","description":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","kind":"script","risk":"high","side_effects":["Applies the plan — creates, modifies, and destroys real infrastructure.","Cannot be reversed; a mistaken apply needs a corrective run.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to confirm (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Confirm a reviewed run","args":{"comment":"Reviewed via emisar","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.cancel_run","title":"POST /runs/<id>/actions/cancel","summary":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","description":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Interrupts the run; an apply already in flight stops partway through.","Can leave infrastructure partially changed and state needing reconciliation.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to cancel (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Interrupt a stuck run","args":{"comment":"Interrupting a hung plan","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.create_plan_only_run","title":"POST /runs (plan-only)","summary":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","description":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates no applyable plan; a plan-only run cannot be confirmed."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to plan against (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Ask what a workspace would change","args":{"message":"Pre-change review","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["what would change","speculative plan","dry run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.discard_run","title":"POST /runs/<id>/actions/discard","summary":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","description":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Abandons the pending plan; it can never be applied afterwards.","Unlocks the workspace, letting a queued run proceed.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to discard (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Discard a plan that should not ship","args":{"comment":"Superseded","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.force_unlock_workspace","title":"POST /workspaces/<id>/actions/force-unlock","summary":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team.","description":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team. This is the recovery for a dead run that never released its lock — but if that run is in fact still applying, breaking the lock lets a second writer at the state and can corrupt or lose it. First read the holder from tfc.workspace_details and confirm with tfc.run_details that it is finished, and when a plain unlock answers 503 (state still finalizing), retry tfc.unlock_workspace instead of escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"high","side_effects":["Breaks any lock, including a live run's — an apply still writing then shares state with the next writer, which can corrupt or lose state.","Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Requires a user or team token with admin access to the workspace."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to force-unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"Break a dead run's lock","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["force unlock a stuck workspace","lock held by a dead run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.list_organizations","title":"GET /organizations","summary":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","description":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":20,"description":"Organizations per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Organizations this token can reach","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"organizations":{"items":{"additionalProperties":false,"properties":{"created_at":{"type":"string"},"email":{"maxLength":100,"type":"string"},"name":{"type":"string"}},"required":["name","email","created_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["organizations","next_page"],"type":"object"}},{"id":"tfc.list_runs","title":"GET /workspaces/<id>/runs","summary":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","description":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace ID from list_workspaces (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Runs per page.","validation":{"min":1,"max":12}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent runs in a workspace","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["run waiting for approval","pending apply","stuck run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"maxItems":12,"type":"array"}},"required":["runs","next_page"],"type":"object"}},{"id":"tfc.list_workspaces","title":"GET /organizations/<name>/workspaces","summary":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","description":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"page_size","type":"integer","required":false,"default":20,"description":"Workspaces per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Workspaces in an organization","args":{"organization":"example-corp"}}],"search_terms":["which workspaces auto-apply","locked workspace"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"workspaces":{"items":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","resource_count","updated_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["workspaces","next_page"],"type":"object"}},{"id":"tfc.lock_workspace","title":"POST /workspaces/<id>/actions/lock","summary":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","description":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["New and queued runs hold before planning or applying until the workspace is unlocked.","Blocks state writes; reversible with tfc.unlock_workspace.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to lock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"reason","type":"string","required":false,"default":"","description":"Reason recorded on the lock in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Freeze a workspace during an investigation","args":{"reason":"Incident 4821 investigation","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["freeze a workspace","maintenance lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.plan_summary","title":"Project an HCP Terraform plan into a reviewable summary","summary":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes.","description":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, names, and the bounded `replace_paths` that identify replacement-forcing attributes — because the structured plan HCP Terraform serves carries every value in cleartext, sensitive ones included. Needs a user or team token with admin access to the workspace; tfc.run_details gives counts on a read-only token.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET, followed to the API's presigned redirect.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Review what a run would change","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["review plan","what will change","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"replace_paths":{"items":{"maxLength":32,"type":"string"},"maxItems":2,"type":"array"},"replace_paths_truncated":{"minimum":0,"type":"integer"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason","replace_paths","replace_paths_truncated"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"hcp_plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","truncated"],"type":"object"}},{"id":"tfc.retry_run","title":"POST /runs (retry a failed run's exact configuration)","summary":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version.","description":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version. Only an errored, canceled, force-canceled, or discarded source can be retried, and both IDs are taken from the fetched source run, never from the caller. The new run is created with plan-only and auto-apply explicitly false, so nothing is applied until a human confirms it through tfc.apply_run. Only the configuration is pinned: workspace variables and provider state are re-read when the new run plans.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates a confirmable run; applying it still requires tfc.apply_run."],"args":[{"name":"source_run_id","type":"string","required":true,"description":"Errored, canceled, force-canceled, or discarded run to retry (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the new run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Retry an errored run unchanged","args":{"message":"Retry after fixing provider credentials","source_run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["retry failed run","re-run terraform","rerun errored run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"configuration_version_id":{"type":"string"},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"source_run_id":{"type":"string"}},"required":["run","source_run_id","configuration_version_id"],"type":"object"}},{"id":"tfc.run_details","title":"GET /runs/<id>?include=plan","summary":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","description":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"One run and its plan counts","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["how many resources will be destroyed","blast radius"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"plan":{"additionalProperties":false,"properties":{"has_changes":{"type":"boolean"},"id":{"type":"string"},"resource_additions":{"type":"integer"},"resource_changes":{"type":"integer"},"resource_destructions":{"type":"integer"},"resource_imports":{"type":"integer"},"status":{"type":"string"}},"required":["id","status","has_changes","resource_additions","resource_changes","resource_destructions","resource_imports"],"type":["object","null"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","plan"],"type":"object"}},{"id":"tfc.run_diagnostics","title":"Diagnose a failed run from its plan or apply log","summary":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped.","description":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped. Provider logs can carry sensitive operational values, so this read is medium risk and policy-gated even though it changes nothing. The presigned log URL HCP returns is fetched but never emitted, and a missing or unreadable log is reported explicitly instead of passing as an empty tail.","kind":"script","risk":"medium","side_effects":["Two read-only HTTP GETs — the run, then its phase's presigned log URL.","Emits provider log content, which can include sensitive operational values.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Errored or canceled run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Read why a run errored","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["why did the run fail","errored run","terraform apply error log","diagnose failed run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"diagnostics":{"additionalProperties":false,"properties":{"ended_at":{"type":"string"},"started_at":{"type":"string"},"status":{"type":"string"}},"required":["status","started_at","ended_at"],"type":"object"},"log":{"additionalProperties":false,"properties":{"available":{"type":"boolean"},"reason":{"type":"string"},"tail":{"items":{"maxLength":2048,"type":"string"},"maxItems":60,"type":"array"}},"required":["available"],"type":"object"},"phase":{"enum":["plan","apply"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","phase","diagnostics","log"],"type":"object"}},{"id":"tfc.unlock_workspace","title":"POST /workspaces/<id>/actions/unlock","summary":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","description":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Cannot release a lock held by a run or a different user; that answers 409.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"End a maintenance freeze","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["unfreeze a workspace","release the workspace lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.workspace_details","title":"GET /organizations/<name>/workspaces/<workspace>","summary":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","description":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"workspace","type":"string","required":true,"description":"Workspace name, as shown in HCP Terraform.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,89}$","max_length":90}}],"examples":[{"title":"Why is production-network locked","args":{"organization":"example-corp","workspace":"production-network"}}],"search_terms":["who locked this workspace","workspace lock holder"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}}]},{"version":"0.7.0","content_hash":"sha256:3f34cba5aaaaf61b36480ec3c77f55f7dae0da90a851455ddf9beeda1a3e0baa","tarball_url":"https://registry.emisar.dev/v1/packs/hcp-terraform/0.7.0/3f34cba5aaaaf61b36480ec3c77f55f7dae0da90a851455ddf9beeda1a3e0baa/pack.tar.gz","actions":[{"id":"tfc.apply_run","title":"POST /runs/<id>/actions/apply","summary":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","description":"Confirm a planned run so HCP Terraform applies it. This is the real apply — it creates, changes, and destroys whatever the plan says, and it cannot be undone from here. Review the plan first with tfc.plan_summary or tfc.run_details. Returns the run's state after confirmation.","kind":"script","risk":"high","side_effects":["Applies the plan — creates, modifies, and destroys real infrastructure.","Cannot be reversed; a mistaken apply needs a corrective run.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to confirm (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Confirm a reviewed run","args":{"comment":"Reviewed via emisar","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.cancel_run","title":"POST /runs/<id>/actions/cancel","summary":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","description":"Interrupt a run that is currently planning or applying. Cancelling mid-apply stops Terraform partway, so the workspace can be left with some changes made and others not; prefer discard_run for a run that has only planned. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Interrupts the run; an apply already in flight stops partway through.","Can leave infrastructure partially changed and state needing reconciliation.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to cancel (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Interrupt a stuck run","args":{"comment":"Interrupting a hung plan","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.create_plan_only_run","title":"POST /runs (plan-only)","summary":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","description":"Queue a speculative plan-only run against a workspace's current configuration. A plan-only run can never be applied, so this asks \"what would change?\" without putting an applyable plan in front of anyone. Review the result with tfc.plan_summary once it finishes.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates no applyable plan; a plan-only run cannot be confirmed."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to plan against (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Ask what a workspace would change","args":{"message":"Pre-change review","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["what would change","speculative plan","dry run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.discard_run","title":"POST /runs/<id>/actions/discard","summary":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","description":"Discard a run awaiting confirmation so its plan is never applied and the workspace unlocks for the next run. Discards no infrastructure — it throws away the pending plan. Returns the run's state afterwards.","kind":"script","risk":"medium","side_effects":["Abandons the pending plan; it can never be applied afterwards.","Unlocks the workspace, letting a queued run proceed.","Requires a user or team token with permission to apply runs."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID to discard (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"comment","type":"string","required":false,"default":"","description":"Comment recorded on the run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Discard a plan that should not ship","args":{"comment":"Superseded","run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run"],"type":"object"}},{"id":"tfc.force_unlock_workspace","title":"POST /workspaces/<id>/actions/force-unlock","summary":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team.","description":"Force-unlock a workspace, breaking a lock held by a run, another user, or a team. This is the recovery for a dead run that never released its lock — but if that run is in fact still applying, breaking the lock lets a second writer at the state and can corrupt or lose it. First read the holder from tfc.workspace_details and confirm with tfc.run_details that it is finished, and when a plain unlock answers 503 (state still finalizing), retry tfc.unlock_workspace instead of escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"high","side_effects":["Breaks any lock, including a live run's — an apply still writing then shares state with the next writer, which can corrupt or lose state.","Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Requires a user or team token with admin access to the workspace."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to force-unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"Break a dead run's lock","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["force unlock a stuck workspace","lock held by a dead run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.list_organizations","title":"GET /organizations","summary":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","description":"List the HCP Terraform organizations this token can see, with the contact email and creation date of each. Use it to confirm the token authenticates and to find the organization name the workspace actions need.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"page_size","type":"integer","required":false,"default":20,"description":"Organizations per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Organizations this token can reach","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"organizations":{"items":{"additionalProperties":false,"properties":{"created_at":{"type":"string"},"email":{"maxLength":100,"type":"string"},"name":{"type":"string"}},"required":["name","email","created_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["organizations","next_page"],"type":"object"}},{"id":"tfc.list_runs","title":"GET /workspaces/<id>/runs","summary":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","description":"List a workspace's runs with status, the operator's message (clipped to 100 characters), whether the run destroys or is plan-only, and which of confirm/discard/cancel the run will currently accept. Use it to find a run awaiting confirmation; page on next_page for older runs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace ID from list_workspaces (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"page_size","type":"integer","required":false,"default":12,"description":"Runs per page.","validation":{"min":1,"max":12}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Recent runs in a workspace","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["run waiting for approval","pending apply","stuck run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"runs":{"items":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"maxItems":12,"type":"array"}},"required":["runs","next_page"],"type":"object"}},{"id":"tfc.list_workspaces","title":"GET /organizations/<name>/workspaces","summary":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","description":"List an organization's workspaces with their execution mode, Terraform version, auto-apply setting, lock state, and resource count. Use it to find the workspace ID the run actions need, or to see which workspaces apply without review.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"page_size","type":"integer","required":false,"default":20,"description":"Workspaces per page.","validation":{"min":1,"max":20}},{"name":"page","type":"integer","required":false,"default":1,"description":"Page number, starting at 1.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Workspaces in an organization","args":{"organization":"example-corp"}}],"search_terms":["which workspaces auto-apply","locked workspace"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"next_page":{"type":["integer","null"]},"workspaces":{"items":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","resource_count","updated_at"],"type":"object"},"maxItems":20,"type":"array"}},"required":["workspaces","next_page"],"type":"object"}},{"id":"tfc.lock_workspace","title":"POST /workspaces/<id>/actions/lock","summary":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","description":"Lock a workspace and record why, so queued and new runs hold before planning or applying and nothing can write its state until it is unlocked. Speculative plan-only runs still work. Reversible with tfc.unlock_workspace; a workspace that is already locked answers 409. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["New and queued runs hold before planning or applying until the workspace is unlocked.","Blocks state writes; reversible with tfc.unlock_workspace.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to lock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}},{"name":"reason","type":"string","required":false,"default":"","description":"Reason recorded on the lock in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Freeze a workspace during an investigation","args":{"reason":"Incident 4821 investigation","workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["freeze a workspace","maintenance lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.plan_summary","title":"Project an HCP Terraform plan into a reviewable summary","summary":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes.","description":"List what a run's plan would create, update, delete, or replace, with per-action counts, drift, and planned output changes. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, and names — because the structured plan HCP Terraform serves carries every value in cleartext, sensitive ones included. Needs a user or team token with admin access to the workspace; tfc.run_details gives counts on a read-only token.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET, followed to the API's presigned redirect.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Review what a run would change","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["review plan","what will change","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"hcp_plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","truncated"],"type":"object"}},{"id":"tfc.retry_run","title":"POST /runs (retry a failed run's exact configuration)","summary":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version.","description":"Retry a failed run by creating a new standard run from the source run's exact workspace and configuration version. Only an errored, canceled, force-canceled, or discarded source can be retried, and both IDs are taken from the fetched source run, never from the caller. The new run is created with plan-only and auto-apply explicitly false, so nothing is applied until a human confirms it through tfc.apply_run. Only the configuration is pinned: workspace variables and provider state are re-read when the new run plans.","kind":"script","risk":"medium","side_effects":["Queues work on HCP Terraform's runners and consumes plan minutes.","Calls every provider's read API to refresh state — quota usage applies.","Creates a confirmable run; applying it still requires tfc.apply_run."],"args":[{"name":"source_run_id","type":"string","required":true,"description":"Errored, canceled, force-canceled, or discarded run to retry (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}},{"name":"message","type":"string","required":false,"default":"","description":"Message recorded on the new run in HCP Terraform.","validation":{"max_length":512}}],"examples":[{"title":"Retry an errored run unchanged","args":{"message":"Retry after fixing provider credentials","source_run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["retry failed run","re-run terraform","rerun errored run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"configuration_version_id":{"type":"string"},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"},"source_run_id":{"type":"string"}},"required":["run","source_run_id","configuration_version_id"],"type":"object"}},{"id":"tfc.run_details","title":"GET /runs/<id>?include=plan","summary":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","description":"Show one run with its plan's add / change / destroy / import counts. This is the review a token holding only \"read runs\" can perform — tfc.plan_summary returns the per-resource detail but requires workspace admin. Use it to size a run's blast radius before confirming it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"One run and its plan counts","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["how many resources will be destroyed","blast radius"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"plan":{"additionalProperties":false,"properties":{"has_changes":{"type":"boolean"},"id":{"type":"string"},"resource_additions":{"type":"integer"},"resource_changes":{"type":"integer"},"resource_destructions":{"type":"integer"},"resource_imports":{"type":"integer"},"status":{"type":"string"}},"required":["id","status","has_changes","resource_additions","resource_changes","resource_destructions","resource_imports"],"type":["object","null"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","plan"],"type":"object"}},{"id":"tfc.run_diagnostics","title":"Diagnose a failed run from its plan or apply log","summary":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped.","description":"Show why a run failed: picks the phase that failed — the apply when it errored or was canceled, otherwise the plan — and returns that phase's status and timestamps with a bounded tail of its log, the last 60 lines capped at 2 KiB with control codes stripped. Provider logs can carry sensitive operational values, so this read is medium risk and policy-gated even though it changes nothing. The presigned log URL HCP returns is fetched but never emitted, and a missing or unreadable log is reported explicitly instead of passing as an empty tail.","kind":"script","risk":"medium","side_effects":["Two read-only HTTP GETs — the run, then its phase's presigned log URL.","Emits provider log content, which can include sensitive operational values.","Read-only."],"args":[{"name":"run_id","type":"string","required":true,"description":"Errored or canceled run ID from list_runs (run-…).","validation":{"pattern":"^run-[A-Za-z0-9]{1,32}$","max_length":36}}],"examples":[{"title":"Read why a run errored","args":{"run_id":"run-4Qm7TvLpXsRbNc2d"}}],"search_terms":["why did the run fail","errored run","terraform apply error log","diagnose failed run"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"diagnostics":{"additionalProperties":false,"properties":{"ended_at":{"type":"string"},"started_at":{"type":"string"},"status":{"type":"string"}},"required":["status","started_at","ended_at"],"type":"object"},"log":{"additionalProperties":false,"properties":{"available":{"type":"boolean"},"reason":{"type":"string"},"tail":{"items":{"maxLength":2048,"type":"string"},"maxItems":60,"type":"array"}},"required":["available"],"type":"object"},"phase":{"enum":["plan","apply"]},"run":{"additionalProperties":false,"properties":{"actions":{"additionalProperties":false,"properties":{"cancelable":{"type":"boolean"},"confirmable":{"type":"boolean"},"discardable":{"type":"boolean"}},"required":["confirmable","discardable","cancelable"],"type":"object"},"created_at":{"type":"string"},"has_changes":{"type":"boolean"},"id":{"type":"string"},"is_destroy":{"type":"boolean"},"message":{"maxLength":100,"type":"string"},"plan_only":{"type":"boolean"},"source":{"type":"string"},"status":{"type":"string"},"workspace_id":{"type":"string"}},"required":["id","status","message","is_destroy","plan_only","has_changes","source","created_at","workspace_id","actions"],"type":"object"}},"required":["run","phase","diagnostics","log"],"type":"object"}},{"id":"tfc.unlock_workspace","title":"POST /workspaces/<id>/actions/unlock","summary":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","description":"Unlock a workspace so pending runs can proceed again. Releases a lock the token's own user placed; a lock held by a run or by a different user answers 409 and takes tfc.force_unlock_workspace instead. A 503 means HCP Terraform is still finalizing the latest state version — retry the unlock rather than escalating to force. Returns the workspace's lock state afterwards.","kind":"script","risk":"medium","side_effects":["Pending runs proceed; on an auto-apply workspace an apply can start without further review.","Cannot release a lock held by a run or a different user; that answers 409.","Requires a user or team token with the workspace's lock/unlock permission."],"args":[{"name":"workspace_id","type":"string","required":true,"description":"Workspace to unlock (ws-…).","validation":{"pattern":"^ws-[A-Za-z0-9]{1,32}$","max_length":35}}],"examples":[{"title":"End a maintenance freeze","args":{"workspace_id":"ws-8Rp2nKcQvWxYzA1b"}}],"search_terms":["unfreeze a workspace","release the workspace lock"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}},{"id":"tfc.workspace_details","title":"GET /organizations/<name>/workspaces/<workspace>","summary":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","description":"Show one workspace by name — its execution mode, Terraform version, auto-apply setting, VCS repository and working directory, resource count, and its lock state including who holds the lock and why. This is the read that answers \"why is this workspace locked, and whose lock is it\" before anyone reaches for force-unlock, and the id it returns is what the run and lock actions take.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the HCP Terraform API.","Read-only."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization name.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$","max_length":63}},{"name":"workspace","type":"string","required":true,"description":"Workspace name, as shown in HCP Terraform.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,89}$","max_length":90}}],"examples":[{"title":"Why is production-network locked","args":{"organization":"example-corp","workspace":"production-network"}}],"search_terms":["who locked this workspace","workspace lock holder"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"workspace":{"additionalProperties":false,"properties":{"auto_apply":{"type":"boolean"},"current_run_id":{"type":["string","null"]},"execution_mode":{"type":"string"},"id":{"type":"string"},"locked":{"type":"boolean"},"locked_by":{"additionalProperties":false,"properties":{"id":{"maxLength":48,"type":"string"},"type":{"maxLength":24,"type":"string"}},"required":["type","id"],"type":["object","null"]},"locked_reason":{"maxLength":160,"type":"string"},"name":{"maxLength":90,"type":"string"},"resource_count":{"type":"integer"},"terraform_version":{"maxLength":64,"type":"string"},"updated_at":{"type":"string"},"vcs_repo":{"additionalProperties":false,"properties":{"branch":{"maxLength":80,"type":"string"},"identifier":{"maxLength":120,"type":"string"}},"required":["identifier","branch"],"type":["object","null"]},"working_directory":{"maxLength":120,"type":"string"}},"required":["id","name","execution_mode","terraform_version","auto_apply","locked","locked_reason","locked_by","current_run_id","vcs_repo","working_directory","resource_count","updated_at"],"type":"object"}},"required":["workspace"],"type":"object"}}]}]},{"id":"iperf3","name":"iperf3 network throughput","version":"0.1.1","description":"Active network throughput measurement with iperf3 — TCP bandwidth and UDP jitter / packet loss — between two nodes in the fleet. Run the one-shot server on one runner, then probe it with the client from another. Use to answer \"what is the real bandwidth (or loss) between these two hosts?\"","vendor":"emisar","homepage":"https://emisar.dev/packs/iperf3","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/iperf3","content_hash":"sha256:7797e9b78d987a5dd3876fb63515a2ee4592789309ec17efa96a0c2522133bad","tarball_url":"https://registry.emisar.dev/v1/packs/iperf3/0.1.1/7797e9b78d987a5dd3876fb63515a2ee4592789309ec17efa96a0c2522133bad/pack.tar.gz","requires":{"os":["linux"],"binaries":["iperf3"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Needs no host-side credentials — just iperf3 on PATH and a network path between the two runners. Start iperf3.server on one node, then run iperf3.client / iperf3.udp on another node pointed at it. The server is one-shot: it serves a single test and exits, so nothing is left listening.","notes":["Run iperf3.server on the target first (it listens for up to idle_timeout seconds); one server handles both TCP and UDP clients. Dispatch it async (wait=false), then run the client within that window.","If no server is listening, the client's control connection is refused and the test fails fast.","Throughput tests generate sustained traffic at up to line rate for the test duration — keep `duration` short and cap it with `bitrate` on shared or production paths.","Every iperf3 action is medium-risk (policy-gated): the server opens a transient inbound port and the client/udp probes push sustained, link-saturating traffic. iperf3 changes no host state — it only moves test traffic — but that network blast radius is why the whole pack is gated."],"verify":"iperf3.version"},"actions":[{"id":"iperf3.client","title":"iperf3 TCP throughput test","summary":"Measure TCP throughput to a target host running an iperf3 server (`iperf3 -s`).","description":"Measure TCP throughput to a target host running an iperf3 server (`iperf3 -s`). Reports bits/sec, retransmits, and per-stream detail as JSON. Use to answer \"what is the real bandwidth between these two hosts?\" — e.g. diagnosing slow replication, backups, or a suspect link. Set reverse=true to measure the download direction (server → runner). The target MUST already be running an iperf3 server; the test generates sustained traffic for `duration` seconds and can saturate a shared link, so cap it with `bitrate` and keep `duration` short on production paths.","kind":"exec","risk":"medium","side_effects":["Opens a TCP control + data connection to the target's iperf3 server (default port 5201).","Generates sustained traffic at up to line rate (unless `bitrate` caps it) for the test duration — can saturate a shared link.","Read-only on both hosts; no state is changed."],"args":[{"name":"host","type":"string","required":true,"description":"Target host (hostname, IPv4, or IPv6) running an iperf3 server.","validation":{"pattern":"^[a-zA-Z0-9.\\-:]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":5201,"description":"iperf3 server port.","validation":{"min":1,"max":65535}},{"name":"duration","type":"integer","required":false,"default":10,"description":"Test duration in seconds.","validation":{"min":1,"max":30}},{"name":"parallel","type":"integer","required":false,"default":1,"description":"Number of parallel TCP streams.","validation":{"min":1,"max":16}},{"name":"bitrate","type":"string","required":false,"default":"0","description":"Target bitrate cap in bits/sec, optional K/M/G suffix (e.g. \"500M\"). \"0\" means unlimited (measure true capacity).","validation":{"pattern":"^[0-9]{1,7}[KMGkmg]?$"}},{"name":"reverse","type":"boolean","required":false,"default":false,"description":"Reverse mode — the server sends and the runner receives (measures the download direction)."}],"examples":[{"title":"10s TCP test to 10.0.0.5","args":{"host":"10.0.0.5"}},{"title":"Download direction, 4 streams, capped at 500 Mbit","args":{"bitrate":"500M","host":"10.0.0.5","parallel":4,"reverse":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -- iperf3 -c \"$HOST\" -p \"$PORT\" -t \"$DURATION\" -P \"$PARALLEL\" -b \"$BITRATE\" --connect-timeout 5000 -J; [ \"$REVERSE\" = \"true\" ] && set -- \"$@\" -R; exec \"$@\""]}},{"id":"iperf3.server","title":"iperf3 one-shot server","summary":"Run a one-shot iperf3 server: listen on a port, accept a single throughput test from one client, print the server-side result as JSON, and exit.","description":"Run a one-shot iperf3 server: listen on a port, accept a single throughput test from one client, print the server-side result as JSON, and exit. Pair it with iperf3.client / iperf3.udp on another node — start the server here, then run the client there within the listen window. One server handles both TCP and UDP clients. It self-terminates after idle_timeout seconds if no client connects (and is bounded by the action timeout), so it never leaves a lingering daemon or open port. Optionally restrict the listener to a single interface with `bind`.","kind":"exec","risk":"medium","side_effects":["Opens an inbound listening port (default 5201) for up to idle_timeout seconds.","Accepts ONE throughput test from a connecting client and discards the data; self-closes after that test or on idle timeout.","Opens the host to inbound connections on that port while it waits — anyone who can reach it may run a test through it or occupy the one-off slot.","Changes no host state and leaves no daemon running — the listener is transient and self-closing."],"args":[{"name":"port","type":"integer","required":false,"default":5201,"description":"Port to listen on.","validation":{"min":1,"max":65535}},{"name":"idle_timeout","type":"integer","required":false,"default":30,"description":"Seconds to wait for a client before giving up (also the stuck-guard during a test). The server exits after this many idle seconds if no client connects. Maps to iperf3 --idle-timeout.","validation":{"min":1,"max":60}},{"name":"bind","type":"string","required":false,"default":"","description":"Restrict the listener to one interface by address (e.g. \"10.0.0.5\"). Empty (the default) listens on all interfaces.","validation":{"pattern":"^[a-zA-Z0-9.\\-:]{0,253}$"}}],"examples":[{"title":"Listen on 5201 for one test, give up after 30s idle","args":{}},{"title":"Listen only on the private interface","args":{"bind":"10.0.0.5"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -- iperf3 -s -1 --idle-timeout \"$IDLE_TIMEOUT\" -p \"$PORT\" -J; [ -n \"$BIND\" ] && set -- \"$@\" -B \"$BIND\"; exec \"$@\""]}},{"id":"iperf3.udp","title":"iperf3 UDP jitter + loss test","summary":"Measure UDP throughput, jitter, and packet loss to a target host running an iperf3 server (`iperf3 -s`). Sends a UDP stream at the target `bitrate` and reports jitter (ms) and lost-packet percentage as JSON. Use to check a path for loss or jitter (VoIP, video, real-time links) or to probe how much a link drops at a given rate. Set reverse=true to test the download direction (server → runner). The target MUST already be running an iperf3 server; generates sustained UDP traffic for `duration` seconds.","description":"Measure UDP throughput, jitter, and packet loss to a target host running an iperf3 server (`iperf3 -s`). Sends a UDP stream at the target `bitrate` and reports jitter (ms) and lost-packet percentage as JSON. Use to check a path for loss or jitter (VoIP, video, real-time links) or to probe how much a link drops at a given rate. Set reverse=true to test the download direction (server → runner). The target MUST already be running an iperf3 server; generates sustained UDP traffic for `duration` seconds.","kind":"exec","risk":"medium","side_effects":["Sends a UDP stream to the target's iperf3 server (default port 5201) at the target bitrate.","Generates sustained UDP traffic for the test duration — can congest a shared link.","Read-only on both hosts; no state is changed."],"args":[{"name":"host","type":"string","required":true,"description":"Target host (hostname, IPv4, or IPv6) running an iperf3 server.","validation":{"pattern":"^[a-zA-Z0-9.\\-:]{1,253}$"}},{"name":"bitrate","type":"string","required":true,"description":"Target UDP bitrate in bits/sec, optional K/M/G suffix (e.g. \"50M\"). This is the rate the sender aims for; the report shows how much of it arrived.","validation":{"pattern":"^[1-9][0-9]{0,6}[KMGkmg]?$"}},{"name":"port","type":"integer","required":false,"default":5201,"description":"iperf3 server port.","validation":{"min":1,"max":65535}},{"name":"duration","type":"integer","required":false,"default":10,"description":"Test duration in seconds.","validation":{"min":1,"max":30}},{"name":"reverse","type":"boolean","required":false,"default":false,"description":"Reverse mode — the server sends and the runner receives (measures the download direction)."}],"examples":[{"title":"10s UDP test at 50 Mbit to 10.0.0.5","args":{"bitrate":"50M","host":"10.0.0.5"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -- iperf3 -c \"$HOST\" -p \"$PORT\" -u -b \"$BITRATE\" -t \"$DURATION\" --connect-timeout 5000 -J; [ \"$REVERSE\" = \"true\" ] && set -- \"$@\" -R; exec \"$@\""]}},{"id":"iperf3.version","title":"iperf3 version + build info","summary":"Show the installed iperf3 version and build info (cJSON / OpenSSL). Read-only local check with no network — use it to confirm the runner actually has iperf3 before dispatching a throughput test.","description":"Show the installed iperf3 version and build info (cJSON / OpenSSL). Read-only local check with no network — use it to confirm the runner actually has iperf3 before dispatching a throughput test.","kind":"exec","risk":"medium","side_effects":["Runs `iperf3 --version` locally.","Read-only; no network traffic."],"args":[],"examples":[{"title":"Show iperf3 version","args":{}}],"search_terms":[],"command":{"binary":"iperf3","argv":["--version"]}}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:4a80767927aaa86d9a4883735afcc2d8a03b745031451f7a0c68244c65d99349","tarball_url":"https://registry.emisar.dev/v1/packs/iperf3/0.1.0/4a80767927aaa86d9a4883735afcc2d8a03b745031451f7a0c68244c65d99349/pack.tar.gz","actions":[{"id":"iperf3.client","title":"iperf3 TCP throughput test","summary":"Measure TCP throughput to a target host running an iperf3 server (`iperf3 -s`).","description":"Measure TCP throughput to a target host running an iperf3 server (`iperf3 -s`). Reports bits/sec, retransmits, and per-stream detail as JSON. Use to answer \"what is the real bandwidth between these two hosts?\" — e.g. diagnosing slow replication, backups, or a suspect link. Set reverse=true to measure the download direction (server → runner). The target MUST already be running an iperf3 server; the test generates sustained traffic for `duration` seconds and can saturate a shared link, so cap it with `bitrate` and keep `duration` short on production paths.","kind":"exec","risk":"medium","side_effects":["Opens a TCP control + data connection to the target's iperf3 server (default port 5201).","Generates sustained traffic at up to line rate (unless `bitrate` caps it) for the test duration — can saturate a shared link.","Read-only on both hosts; no state is changed."],"args":[{"name":"host","type":"string","required":true,"description":"Target host (hostname, IPv4, or IPv6) running an iperf3 server.","validation":{"pattern":"^[a-zA-Z0-9.\\-:]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":5201,"description":"iperf3 server port.","validation":{"min":1,"max":65535}},{"name":"duration","type":"integer","required":false,"default":10,"description":"Test duration in seconds.","validation":{"min":1,"max":30}},{"name":"parallel","type":"integer","required":false,"default":1,"description":"Number of parallel TCP streams.","validation":{"min":1,"max":16}},{"name":"bitrate","type":"string","required":false,"default":"0","description":"Target bitrate cap in bits/sec, optional K/M/G suffix (e.g. \"500M\"). \"0\" means unlimited (measure true capacity).","validation":{"pattern":"^[0-9]{1,7}[KMGkmg]?$"}},{"name":"reverse","type":"boolean","required":false,"default":false,"description":"Reverse mode — the server sends and the runner receives (measures the download direction)."}],"examples":[{"title":"10s TCP test to 10.0.0.5","args":{"host":"10.0.0.5"}},{"title":"Download direction, 4 streams, capped at 500 Mbit","args":{"bitrate":"500M","host":"10.0.0.5","parallel":4,"reverse":true}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -- iperf3 -c \"$HOST\" -p \"$PORT\" -t \"$DURATION\" -P \"$PARALLEL\" -b \"$BITRATE\" --connect-timeout 5000 -J; [ \"$REVERSE\" = \"true\" ] && set -- \"$@\" -R; exec \"$@\""]}},{"id":"iperf3.server","title":"iperf3 one-shot server","summary":"Run a one-shot iperf3 server: listen on a port, accept a single throughput test from one client, print the server-side result as JSON, and exit.","description":"Run a one-shot iperf3 server: listen on a port, accept a single throughput test from one client, print the server-side result as JSON, and exit. Pair it with iperf3.client / iperf3.udp on another node — start the server here, then run the client there within the listen window. One server handles both TCP and UDP clients. It self-terminates after idle_timeout seconds if no client connects (and is bounded by the action timeout), so it never leaves a lingering daemon or open port. Optionally restrict the listener to a single interface with `bind`.","kind":"exec","risk":"medium","side_effects":["Opens an inbound listening port (default 5201) for up to idle_timeout seconds.","Accepts ONE throughput test from a connecting client and discards the data; self-closes after that test or on idle timeout.","Opens the host to inbound connections on that port while it waits — anyone who can reach it may run a test through it or occupy the one-off slot.","Changes no host state and leaves no daemon running — the listener is transient and self-closing."],"args":[{"name":"port","type":"integer","required":false,"default":5201,"description":"Port to listen on.","validation":{"min":1,"max":65535}},{"name":"idle_timeout","type":"integer","required":false,"default":30,"description":"Seconds to wait for a client before giving up (also the stuck-guard during a test). The server exits after this many idle seconds if no client connects. Maps to iperf3 --idle-timeout.","validation":{"min":1,"max":60}},{"name":"bind","type":"string","required":false,"default":"","description":"Restrict the listener to one interface by address (e.g. \"10.0.0.5\"). Empty (the default) listens on all interfaces.","validation":{"pattern":"^[a-zA-Z0-9.\\-:]{0,253}$"}}],"examples":[{"title":"Listen on 5201 for one test, give up after 30s idle","args":{}},{"title":"Listen only on the private interface","args":{"bind":"10.0.0.5"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -- iperf3 -s -1 --idle-timeout \"$IDLE_TIMEOUT\" -p \"$PORT\" -J; [ -n \"$BIND\" ] && set -- \"$@\" -B \"$BIND\"; exec \"$@\""]}},{"id":"iperf3.udp","title":"iperf3 UDP jitter + loss test","summary":"Measure UDP throughput, jitter, and packet loss to a target host running an iperf3 server (`iperf3 -s`). Sends a UDP stream at the target `bitrate` and reports jitter (ms) and lost-packet percentage as JSON. Use to check a path for loss or jitter (VoIP, video, real-time links) or to probe how much a link drops at a given rate. Set reverse=true to test the download direction (server → runner). The target MUST already be running an iperf3 server; generates sustained UDP traffic for `duration` seconds.","description":"Measure UDP throughput, jitter, and packet loss to a target host running an iperf3 server (`iperf3 -s`). Sends a UDP stream at the target `bitrate` and reports jitter (ms) and lost-packet percentage as JSON. Use to check a path for loss or jitter (VoIP, video, real-time links) or to probe how much a link drops at a given rate. Set reverse=true to test the download direction (server → runner). The target MUST already be running an iperf3 server; generates sustained UDP traffic for `duration` seconds.","kind":"exec","risk":"medium","side_effects":["Sends a UDP stream to the target's iperf3 server (default port 5201) at the target bitrate.","Generates sustained UDP traffic for the test duration — can congest a shared link.","Read-only on both hosts; no state is changed."],"args":[{"name":"host","type":"string","required":true,"description":"Target host (hostname, IPv4, or IPv6) running an iperf3 server.","validation":{"pattern":"^[a-zA-Z0-9.\\-:]{1,253}$"}},{"name":"bitrate","type":"string","required":true,"description":"Target UDP bitrate in bits/sec, optional K/M/G suffix (e.g. \"50M\"). This is the rate the sender aims for; the report shows how much of it arrived.","validation":{"pattern":"^[1-9][0-9]{0,6}[KMGkmg]?$"}},{"name":"port","type":"integer","required":false,"default":5201,"description":"iperf3 server port.","validation":{"min":1,"max":65535}},{"name":"duration","type":"integer","required":false,"default":10,"description":"Test duration in seconds.","validation":{"min":1,"max":30}},{"name":"reverse","type":"boolean","required":false,"default":false,"description":"Reverse mode — the server sends and the runner receives (measures the download direction)."}],"examples":[{"title":"10s UDP test at 50 Mbit to 10.0.0.5","args":{"bitrate":"50M","host":"10.0.0.5"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -- iperf3 -c \"$HOST\" -p \"$PORT\" -u -b \"$BITRATE\" -t \"$DURATION\" --connect-timeout 5000 -J; [ \"$REVERSE\" = \"true\" ] && set -- \"$@\" -R; exec \"$@\""]}},{"id":"iperf3.version","title":"iperf3 version + build info","summary":"Show the installed iperf3 version and build info (cJSON / OpenSSL). Read-only local check with no network — use it to confirm the runner actually has iperf3 before dispatching a throughput test.","description":"Show the installed iperf3 version and build info (cJSON / OpenSSL). Read-only local check with no network — use it to confirm the runner actually has iperf3 before dispatching a throughput test.","kind":"exec","risk":"medium","side_effects":["Runs `iperf3 --version` locally.","Read-only; no network traffic."],"args":[],"examples":[{"title":"Show iperf3 version","args":{}}],"search_terms":[],"command":{"binary":"iperf3","argv":["--version"]}}]}]},{"id":"iscsi","name":"iSCSI initiator","version":"0.1.6","description":"Inspect the host's iSCSI initiator (open-iscsi): active sessions, per-session detail (targets, connections, negotiated parameters), configured target nodes, and initiator interfaces. Read-only.","vendor":"emisar","homepage":"https://emisar.dev/packs/iscsi","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/iscsi","content_hash":"sha256:2a7249c1497d8e154257f76c42e9e0efeb34c079fe9da07c3e89c0d56ed2c3e8","tarball_url":"https://registry.emisar.dev/v1/packs/iscsi/0.1.6/2a7249c1497d8e154257f76c42e9e0efeb34c079fe9da07c3e89c0d56ed2c3e8/pack.tar.gz","requires":{"os":["linux"],"binaries":["iscsiadm"]},"detect":{"binaries":["iscsiadm"],"processes":["iscsid"],"ports":[]},"setup":{"summary":"Reads the local host's iSCSI initiator state via iscsiadm — no credentials needed. iscsiadm needs root (it reads `/sys` and the initiator DB).","notes":["Running as root applies to every action on that host, not just these; on a dedicated storage host that's expected, and the cloud policy + approval gates still govern what runs."],"host_access":[{"actions":["iscsi.sessions","iscsi.session_detail","iscsi.nodes","iscsi.ifaces"],"requirement":"Read iSCSI netlink, sysfs, and the initiator database as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-iscsi-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root, including actions from other installed packs. iscsiadm receives full initiator and device authority."}]}],"verify":"iscsi.sessions"},"actions":[{"id":"iscsi.ifaces","title":"iscsiadm -m iface","summary":"List initiator interfaces (the iface bindings sessions run over).","description":"List initiator interfaces (the iface bindings sessions run over).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List initiator interfaces","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","iface"]}},{"id":"iscsi.nodes","title":"iscsiadm -m node","summary":"List configured / discovered target nodes in the initiator database.","description":"List configured / discovered target nodes in the initiator database.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List target nodes","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","node"]}},{"id":"iscsi.session_detail","title":"iscsiadm -m session -P 3","summary":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","description":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"Detailed session view","args":{}}],"search_terms":["missing lun"],"command":{"binary":"iscsiadm","argv":["-m","session","-P","3"]}},{"id":"iscsi.sessions","title":"iscsiadm -m session","summary":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","description":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List active sessions","args":{}}],"search_terms":["san connectivity","logged in targets","storage disconnected"],"command":{"binary":"iscsiadm","argv":["-m","session"]}}],"previous_versions":[{"version":"0.1.5","content_hash":"sha256:e4d9018b1228a6f86a6be07ee0fdb8206038a3d1f7e1562911a94a7b009ee6bb","tarball_url":"https://registry.emisar.dev/v1/packs/iscsi/0.1.5/e4d9018b1228a6f86a6be07ee0fdb8206038a3d1f7e1562911a94a7b009ee6bb/pack.tar.gz","actions":[{"id":"iscsi.ifaces","title":"iscsiadm -m iface","summary":"List initiator interfaces (the iface bindings sessions run over).","description":"List initiator interfaces (the iface bindings sessions run over).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List initiator interfaces","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","iface"]}},{"id":"iscsi.nodes","title":"iscsiadm -m node","summary":"List configured / discovered target nodes in the initiator database.","description":"List configured / discovered target nodes in the initiator database.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List target nodes","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","node"]}},{"id":"iscsi.session_detail","title":"iscsiadm -m session -P 3","summary":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","description":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"Detailed session view","args":{}}],"search_terms":["missing lun"],"command":{"binary":"iscsiadm","argv":["-m","session","-P","3"]}},{"id":"iscsi.sessions","title":"iscsiadm -m session","summary":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","description":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List active sessions","args":{}}],"search_terms":["san connectivity","logged in targets","storage disconnected"],"command":{"binary":"iscsiadm","argv":["-m","session"]}}]},{"version":"0.1.3","content_hash":"sha256:28a5418001eb35dc2bf10bb666c7da23787da29d456ce1ad215aace3f8f331d8","tarball_url":"https://registry.emisar.dev/v1/packs/iscsi/0.1.3/28a5418001eb35dc2bf10bb666c7da23787da29d456ce1ad215aace3f8f331d8/pack.tar.gz","actions":[{"id":"iscsi.ifaces","title":"iscsiadm -m iface","summary":"List initiator interfaces (the iface bindings sessions run over).","description":"List initiator interfaces (the iface bindings sessions run over).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List initiator interfaces","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","iface"]}},{"id":"iscsi.nodes","title":"iscsiadm -m node","summary":"List configured / discovered target nodes in the initiator database.","description":"List configured / discovered target nodes in the initiator database.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List target nodes","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","node"]}},{"id":"iscsi.session_detail","title":"iscsiadm -m session -P 3","summary":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","description":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"Detailed session view","args":{}}],"search_terms":["missing lun"],"command":{"binary":"iscsiadm","argv":["-m","session","-P","3"]}},{"id":"iscsi.sessions","title":"iscsiadm -m session","summary":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","description":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List active sessions","args":{}}],"search_terms":["san connectivity","logged in targets","storage disconnected"],"command":{"binary":"iscsiadm","argv":["-m","session"]}}]},{"version":"0.1.2","content_hash":"sha256:e583967e045d2a88a652056407db619e40447e4dfea0cfd343de384a9f27fa59","tarball_url":"https://registry.emisar.dev/v1/packs/iscsi/0.1.2/e583967e045d2a88a652056407db619e40447e4dfea0cfd343de384a9f27fa59/pack.tar.gz","actions":[{"id":"iscsi.ifaces","title":"iscsiadm -m iface","summary":"List initiator interfaces (the iface bindings sessions run over).","description":"List initiator interfaces (the iface bindings sessions run over).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List initiator interfaces","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","iface"]}},{"id":"iscsi.nodes","title":"iscsiadm -m node","summary":"List configured / discovered target nodes in the initiator database.","description":"List configured / discovered target nodes in the initiator database.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List target nodes","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","node"]}},{"id":"iscsi.session_detail","title":"iscsiadm -m session -P 3","summary":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","description":"Show full per-session detail at print level 3 — target IQN, portal, session and connection state, negotiated parameters, and the attached SCSI disks.","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"Detailed session view","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","session","-P","3"]}},{"id":"iscsi.sessions","title":"iscsiadm -m session","summary":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","description":"List active iSCSI sessions — one line per session (transport, target IQN, sid). Returns nothing and succeeds when there are no active sessions (iscsiadm exits 21 in that case, which is treated as success, not failure).","kind":"exec","risk":"low","side_effects":["One iscsiadm read.","Read-only."],"args":[],"examples":[{"title":"List active sessions","args":{}}],"search_terms":[],"command":{"binary":"iscsiadm","argv":["-m","session"]}}]}]},{"id":"java-jvm","name":"JVM introspection","version":"0.1.17","description":"JVM diagnostics via jcmd/jstack/jmap/jstat/JFR. Requires runner uid and gid to match the JVM process owner — actions return a permission error cleanly when the identity doesn't match.","vendor":"emisar","homepage":"https://emisar.dev/packs/java-jvm","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/java-jvm","content_hash":"sha256:4d809eac2e11c643ebcf0746f311da719f58f00b97f7252f885d9f4172a08c2d","tarball_url":"https://registry.emisar.dev/v1/packs/java-jvm/0.1.17/4d809eac2e11c643ebcf0746f311da719f58f00b97f7252f885d9f4172a08c2d/pack.tar.gz","requires":{"os":["linux"],"binaries":["jcmd"]},"detect":{"binaries":[],"processes":["java"],"ports":[]},"setup":{"summary":"Attaches to local JVM processes on the runner host with the JDK tools (jcmd/jstack/jmap/jstat/JFR) — no credentials needed; the target JVM's pid is passed as an argument.","notes":["The attach API requires the runner to run as the same uid as the target JVM; root and CAP_SYS_PTRACE do not replace HotSpot's effective-user and group check. Install a dedicated runner as the target JVM owner."],"verify":"jvm.vm_uptime"},"actions":[{"id":"jvm.classloader_stats","title":"jcmd VM.classloader_stats","summary":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","description":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Classloader stats for PID 4321","args":{"pid":4321}}],"search_terms":["classloader leak","metaspace leak"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.classloader_stats"]}},{"id":"jvm.heap_dump","title":"jmap -dump:live (heap dump)","summary":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","description":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","kind":"exec","risk":"critical","side_effects":["Triggers full GC.","JVM pause for the duration of the dump (seconds to minutes).","Writes a potentially-multi-GB file to /tmp."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap dump","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jmap","argv":["-dump:live,format=b,file=/tmp/{{ args.pid }}-heap.hprof","{{ args.pid }}"]}},{"id":"jvm.heap_summary","title":"jcmd GC.heap_info","summary":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","description":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","kind":"exec","risk":"low","side_effects":["One jcmd invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap layout","args":{"pid":4321}}],"search_terms":["memory pressure","heap full","old gen full","out of memory"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.heap_info"]}},{"id":"jvm.jcmd_gc_run","title":"jcmd <pid> GC.run","summary":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","description":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","kind":"exec","risk":"medium","side_effects":["Full GC runs.","Pause of seconds on large heaps.","Latency spike during the pause."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":2,"max":4194304}}],"examples":[{"title":"Force GC on a JVM","args":{"pid":12345}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.run"]}},{"id":"jvm.jfr_dump","title":"Dump active JFR recording","summary":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","description":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","kind":"exec","risk":"medium","side_effects":["Writes JFR data to /tmp/<pid>-emisar.jfr.","Recording continues."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Snapshot the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.dump","name=emisar","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_start","title":"Start a Java Flight Recording","summary":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","description":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","kind":"exec","risk":"medium","side_effects":["Starts a JFR session in the JVM.","Writes profile data to /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}},{"name":"duration","type":"integer","required":false,"default":60,"description":"Duration in seconds.","validation":{"min":10,"max":600}}],"examples":[{"title":"Start a 60s recording","args":{"pid":4321}}],"search_terms":["profiling","cpu profile"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.start","name=emisar","duration={{ args.duration }}s","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_stop","title":"Stop active JFR recording","summary":"Stop the \"emisar\" recording and finalize the .jfr file.","description":"Stop the \"emisar\" recording and finalize the .jfr file.","kind":"exec","risk":"medium","side_effects":["Stops the recording.","Finalizes /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"End the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.stop","name=emisar"]}},{"id":"jvm.jmap_histo_live","title":"jmap -histo:live (top 50)","summary":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","description":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","kind":"exec","risk":"medium","side_effects":["Triggers a full GC.","JVM pause for the duration of the GC."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Top retained classes","args":{"pid":4321}}],"search_terms":["memory leak"],"command":{"binary":"/bin/sh","argv":["-c","histo=$(jmap -histo:live {{ args.pid }}); status=$?\nprintf '%s\\n' \"$histo\" | head -50\nexit $status\n"]}},{"id":"jvm.jstack","title":"jstack -l (thread dump)","summary":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","description":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only; introduces a STW pause on the JVM (~ms)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread dump","args":{"pid":4321}}],"search_terms":["app hung","threads stuck","app frozen"],"command":{"binary":"jstack","argv":["-l","{{ args.pid }}"]}},{"id":"jvm.jstack_blocked","title":"jstack filtered to BLOCKED threads","summary":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","description":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Find blocked threads","args":{"pid":4321}}],"search_terms":["deadlock","lock contention"],"command":{"binary":"/bin/sh","argv":["-c","dump=$(jstack -l {{ args.pid }}) || exit 1; printf '%s' \"$dump\" | awk '/^\"/ {hdr=$0; next} /java.lang.Thread.State: BLOCKED/ {print hdr; print; flag=1; next} flag && /^$/ {flag=0; next} flag {print}'"]}},{"id":"jvm.jstat_class","title":"jstat -class","summary":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","description":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","kind":"exec","risk":"low","side_effects":["One jstat invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Class-load stats","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jstat","argv":["-class","{{ args.pid }}"]}},{"id":"jvm.jstat_gc","title":"jstat -gc (10 samples)","summary":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","description":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","kind":"exec","risk":"low","side_effects":["One jstat invocation lasting ~10s.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"10-second GC trace","args":{"pid":4321}}],"search_terms":["gc thrashing","gc storm","memory pressure","heap churn"],"command":{"binary":"jstat","argv":["-gc","{{ args.pid }}","1s","10"]}},{"id":"jvm.perfdata","title":"jcmd PerfCounter.print","summary":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","description":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"PerfData","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","PerfCounter.print"]}},{"id":"jvm.thread_count","title":"OS thread count for a JVM","summary":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","description":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread count","args":{"pid":4321}}],"search_terms":["thread leak"],"command":{"binary":"/bin/sh","argv":["-c","tasks=$(ls /proc/{{ args.pid }}/task) || exit 1; printf '%s\\n' \"$tasks\" | wc -l"]}},{"id":"jvm.vm_flags","title":"jcmd VM.flags","summary":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","description":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Flags for PID 4321","args":{"pid":4321}}],"search_terms":["xmx","heap size"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.flags"]}},{"id":"jvm.vm_system_properties","title":"jcmd VM.system_properties","summary":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()).","description":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()). Use to confirm config overrides took effect — but note this deliberately surfaces every launch -D property, which routinely carries secrets (spring.datasource.password, javax.net.ssl.keyStorePassword, JDBC / cloud credentials). Scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One jcmd call.","Read-only, but exposes every -D launch property (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"System properties","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.system_properties"]}},{"id":"jvm.vm_uptime","title":"jcmd VM.uptime","summary":"Show how long this JVM has been running.","description":"Show how long this JVM has been running.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"JVM uptime","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.uptime"]}}],"previous_versions":[{"version":"0.1.16","content_hash":"sha256:7ff59d0acdd19f8bbf7ec4d953d10c245378c6785ea82eff104f80fab000e459","tarball_url":"https://registry.emisar.dev/v1/packs/java-jvm/0.1.16/7ff59d0acdd19f8bbf7ec4d953d10c245378c6785ea82eff104f80fab000e459/pack.tar.gz","actions":[{"id":"jvm.classloader_stats","title":"jcmd VM.classloader_stats","summary":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","description":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Classloader stats for PID 4321","args":{"pid":4321}}],"search_terms":["classloader leak","metaspace leak"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.classloader_stats"]}},{"id":"jvm.heap_dump","title":"jmap -dump:live (heap dump)","summary":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","description":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","kind":"exec","risk":"critical","side_effects":["Triggers full GC.","JVM pause for the duration of the dump (seconds to minutes).","Writes a potentially-multi-GB file to /tmp."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap dump","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jmap","argv":["-dump:live,format=b,file=/tmp/{{ args.pid }}-heap.hprof","{{ args.pid }}"]}},{"id":"jvm.heap_summary","title":"jcmd GC.heap_info","summary":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","description":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","kind":"exec","risk":"low","side_effects":["One jcmd invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap layout","args":{"pid":4321}}],"search_terms":["memory pressure","heap full","old gen full","out of memory"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.heap_info"]}},{"id":"jvm.jcmd_gc_run","title":"jcmd <pid> GC.run","summary":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","description":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","kind":"exec","risk":"medium","side_effects":["Full GC runs.","Pause of seconds on large heaps.","Latency spike during the pause."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":2,"max":4194304}}],"examples":[{"title":"Force GC on a JVM","args":{"pid":12345}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.run"]}},{"id":"jvm.jfr_dump","title":"Dump active JFR recording","summary":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","description":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","kind":"exec","risk":"medium","side_effects":["Writes JFR data to /tmp/<pid>-emisar.jfr.","Recording continues."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Snapshot the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.dump","name=emisar","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_start","title":"Start a Java Flight Recording","summary":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","description":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","kind":"exec","risk":"medium","side_effects":["Starts a JFR session in the JVM.","Writes profile data to /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}},{"name":"duration","type":"integer","required":false,"default":60,"description":"Duration in seconds.","validation":{"min":10,"max":600}}],"examples":[{"title":"Start a 60s recording","args":{"pid":4321}}],"search_terms":["profiling","cpu profile"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.start","name=emisar","duration={{ args.duration }}s","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_stop","title":"Stop active JFR recording","summary":"Stop the \"emisar\" recording and finalize the .jfr file.","description":"Stop the \"emisar\" recording and finalize the .jfr file.","kind":"exec","risk":"medium","side_effects":["Stops the recording.","Finalizes /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"End the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.stop","name=emisar"]}},{"id":"jvm.jmap_histo_live","title":"jmap -histo:live (top 50)","summary":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","description":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","kind":"exec","risk":"medium","side_effects":["Triggers a full GC.","JVM pause for the duration of the GC."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Top retained classes","args":{"pid":4321}}],"search_terms":["memory leak"],"command":{"binary":"/bin/sh","argv":["-c","histo=$(jmap -histo:live {{ args.pid }}); status=$?\nprintf '%s\\n' \"$histo\" | head -50\nexit $status\n"]}},{"id":"jvm.jstack","title":"jstack -l (thread dump)","summary":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","description":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only; introduces a STW pause on the JVM (~ms)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread dump","args":{"pid":4321}}],"search_terms":["app hung","threads stuck","app frozen"],"command":{"binary":"jstack","argv":["-l","{{ args.pid }}"]}},{"id":"jvm.jstack_blocked","title":"jstack filtered to BLOCKED threads","summary":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","description":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Find blocked threads","args":{"pid":4321}}],"search_terms":["deadlock","lock contention"],"command":{"binary":"/bin/sh","argv":["-c","dump=$(jstack -l {{ args.pid }}) || exit 1; printf '%s' \"$dump\" | awk '/^\"/ {hdr=$0; next} /java.lang.Thread.State: BLOCKED/ {print hdr; print; flag=1; next} flag && /^$/ {flag=0; next} flag {print}'"]}},{"id":"jvm.jstat_class","title":"jstat -class","summary":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","description":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","kind":"exec","risk":"low","side_effects":["One jstat invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Class-load stats","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jstat","argv":["-class","{{ args.pid }}"]}},{"id":"jvm.jstat_gc","title":"jstat -gc (10 samples)","summary":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","description":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","kind":"exec","risk":"low","side_effects":["One jstat invocation lasting ~10s.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"10-second GC trace","args":{"pid":4321}}],"search_terms":["gc thrashing","gc storm","memory pressure","heap churn"],"command":{"binary":"jstat","argv":["-gc","{{ args.pid }}","1s","10"]}},{"id":"jvm.perfdata","title":"jcmd PerfCounter.print","summary":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","description":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"PerfData","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","PerfCounter.print"]}},{"id":"jvm.thread_count","title":"OS thread count for a JVM","summary":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","description":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread count","args":{"pid":4321}}],"search_terms":["thread leak"],"command":{"binary":"/bin/sh","argv":["-c","tasks=$(ls /proc/{{ args.pid }}/task) || exit 1; printf '%s\\n' \"$tasks\" | wc -l"]}},{"id":"jvm.vm_flags","title":"jcmd VM.flags","summary":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","description":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Flags for PID 4321","args":{"pid":4321}}],"search_terms":["xmx","heap size"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.flags"]}},{"id":"jvm.vm_system_properties","title":"jcmd VM.system_properties","summary":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()).","description":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()). Use to confirm config overrides took effect — but note this deliberately surfaces every launch -D property, which routinely carries secrets (spring.datasource.password, javax.net.ssl.keyStorePassword, JDBC / cloud credentials). Scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One jcmd call.","Read-only, but exposes every -D launch property (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"System properties","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.system_properties"]}},{"id":"jvm.vm_uptime","title":"jcmd VM.uptime","summary":"Show how long this JVM has been running.","description":"Show how long this JVM has been running.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"JVM uptime","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.uptime"]}}]},{"version":"0.1.15","content_hash":"sha256:c8af51183cfa5457f57c8770d596b799e0d8d443b65425f92bd077ebf1669406","tarball_url":"https://registry.emisar.dev/v1/packs/java-jvm/0.1.15/c8af51183cfa5457f57c8770d596b799e0d8d443b65425f92bd077ebf1669406/pack.tar.gz","actions":[{"id":"jvm.classloader_stats","title":"jcmd VM.classloader_stats","summary":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","description":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Classloader stats for PID 4321","args":{"pid":4321}}],"search_terms":["classloader leak","metaspace leak"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.classloader_stats"]}},{"id":"jvm.heap_dump","title":"jmap -dump:live (heap dump)","summary":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","description":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","kind":"exec","risk":"critical","side_effects":["Triggers full GC.","JVM pause for the duration of the dump (seconds to minutes).","Writes a potentially-multi-GB file to /tmp."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap dump","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jmap","argv":["-dump:live,format=b,file=/tmp/{{ args.pid }}-heap.hprof","{{ args.pid }}"]}},{"id":"jvm.heap_summary","title":"jcmd GC.heap_info","summary":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","description":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","kind":"exec","risk":"low","side_effects":["One jcmd invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap layout","args":{"pid":4321}}],"search_terms":["memory pressure","heap full","old gen full","out of memory"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.heap_info"]}},{"id":"jvm.jcmd_gc_run","title":"jcmd <pid> GC.run","summary":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","description":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","kind":"exec","risk":"medium","side_effects":["Full GC runs.","Pause of seconds on large heaps.","Latency spike during the pause."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":2,"max":4194304}}],"examples":[{"title":"Force GC on a JVM","args":{"pid":12345}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.run"]}},{"id":"jvm.jfr_dump","title":"Dump active JFR recording","summary":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","description":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","kind":"exec","risk":"medium","side_effects":["Writes JFR data to /tmp/<pid>-emisar.jfr.","Recording continues."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Snapshot the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.dump","name=emisar","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_start","title":"Start a Java Flight Recording","summary":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","description":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","kind":"exec","risk":"medium","side_effects":["Starts a JFR session in the JVM.","Writes profile data to /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}},{"name":"duration","type":"integer","required":false,"default":60,"description":"Duration in seconds.","validation":{"min":10,"max":600}}],"examples":[{"title":"Start a 60s recording","args":{"pid":4321}}],"search_terms":["profiling","cpu profile"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.start","name=emisar","duration={{ args.duration }}s","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_stop","title":"Stop active JFR recording","summary":"Stop the \"emisar\" recording and finalize the .jfr file.","description":"Stop the \"emisar\" recording and finalize the .jfr file.","kind":"exec","risk":"medium","side_effects":["Stops the recording.","Finalizes /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"End the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.stop","name=emisar"]}},{"id":"jvm.jmap_histo_live","title":"jmap -histo:live (top 50)","summary":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","description":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","kind":"exec","risk":"medium","side_effects":["Triggers a full GC.","JVM pause for the duration of the GC."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Top retained classes","args":{"pid":4321}}],"search_terms":["memory leak"],"command":{"binary":"/bin/sh","argv":["-c","histo=$(jmap -histo:live {{ args.pid }}); status=$?\nprintf '%s\\n' \"$histo\" | head -50\nexit $status\n"]}},{"id":"jvm.jstack","title":"jstack -l (thread dump)","summary":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","description":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only; introduces a STW pause on the JVM (~ms)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread dump","args":{"pid":4321}}],"search_terms":["app hung","threads stuck","app frozen"],"command":{"binary":"jstack","argv":["-l","{{ args.pid }}"]}},{"id":"jvm.jstack_blocked","title":"jstack filtered to BLOCKED threads","summary":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","description":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Find blocked threads","args":{"pid":4321}}],"search_terms":["deadlock","lock contention"],"command":{"binary":"/bin/sh","argv":["-c","dump=$(jstack -l {{ args.pid }}) || exit 1; printf '%s' \"$dump\" | awk '/^\"/ {hdr=$0; next} /java.lang.Thread.State: BLOCKED/ {print hdr; print; flag=1; next} flag && /^$/ {flag=0; next} flag {print}'"]}},{"id":"jvm.jstat_class","title":"jstat -class","summary":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","description":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","kind":"exec","risk":"low","side_effects":["One jstat invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Class-load stats","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jstat","argv":["-class","{{ args.pid }}"]}},{"id":"jvm.jstat_gc","title":"jstat -gc (10 samples)","summary":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","description":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","kind":"exec","risk":"low","side_effects":["One jstat invocation lasting ~10s.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"10-second GC trace","args":{"pid":4321}}],"search_terms":["gc thrashing","gc storm","memory pressure","heap churn"],"command":{"binary":"jstat","argv":["-gc","{{ args.pid }}","1s","10"]}},{"id":"jvm.perfdata","title":"jcmd PerfCounter.print","summary":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","description":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"PerfData","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","PerfCounter.print"]}},{"id":"jvm.thread_count","title":"OS thread count for a JVM","summary":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","description":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread count","args":{"pid":4321}}],"search_terms":["thread leak"],"command":{"binary":"/bin/sh","argv":["-c","tasks=$(ls /proc/{{ args.pid }}/task) || exit 1; printf '%s\\n' \"$tasks\" | wc -l"]}},{"id":"jvm.vm_flags","title":"jcmd VM.flags","summary":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","description":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Flags for PID 4321","args":{"pid":4321}}],"search_terms":["xmx","heap size"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.flags"]}},{"id":"jvm.vm_system_properties","title":"jcmd VM.system_properties","summary":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()).","description":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()). Use to confirm config overrides took effect — but note this deliberately surfaces every launch -D property, which routinely carries secrets (spring.datasource.password, javax.net.ssl.keyStorePassword, JDBC / cloud credentials). Scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One jcmd call.","Read-only, but exposes every -D launch property (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"System properties","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.system_properties"]}},{"id":"jvm.vm_uptime","title":"jcmd VM.uptime","summary":"Show how long this JVM has been running.","description":"Show how long this JVM has been running.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"JVM uptime","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.uptime"]}}]},{"version":"0.1.14","content_hash":"sha256:00687eba0f6f17948b2a25e5cbd8264f7280b2ea9365e2bb34896dd9cfe47017","tarball_url":"https://registry.emisar.dev/v1/packs/java-jvm/0.1.14/00687eba0f6f17948b2a25e5cbd8264f7280b2ea9365e2bb34896dd9cfe47017/pack.tar.gz","actions":[{"id":"jvm.classloader_stats","title":"jcmd VM.classloader_stats","summary":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","description":"Show per-classloader statistics — instance count, loaded classes, and chunk/block bytes. Use to spot a class-loader leak. Uses the attach API, so it works on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) where jvm.jstat_class fails.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Classloader stats for PID 4321","args":{"pid":4321}}],"search_terms":["classloader leak","metaspace leak"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.classloader_stats"]}},{"id":"jvm.heap_dump","title":"jmap -dump:live (heap dump)","summary":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","description":"Trigger a full GC, then dump the live heap to /tmp/<pid>-heap.hprof. Can be many GB. Causes a long STW pause (seconds). Use only when you have analyst capacity to load the .hprof and disk space to hold it.","kind":"exec","risk":"critical","side_effects":["Triggers full GC.","JVM pause for the duration of the dump (seconds to minutes).","Writes a potentially-multi-GB file to /tmp."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap dump","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jmap","argv":["-dump:live,format=b,file=/tmp/{{ args.pid }}-heap.hprof","{{ args.pid }}"]}},{"id":"jvm.heap_summary","title":"jcmd GC.heap_info","summary":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","description":"Show heap geometry — used/committed per generation (Eden, Survivor, Old, Metaspace) via the attach API. Works on JDK 9+ where `jmap -heap` was removed, and on JVMs running -XX:+PerfDisableSharedMem (e.g. Cassandra).","kind":"exec","risk":"low","side_effects":["One jcmd invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Heap layout","args":{"pid":4321}}],"search_terms":["memory pressure","heap full","old gen full","out of memory"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.heap_info"]}},{"id":"jvm.jcmd_gc_run","title":"jcmd <pid> GC.run","summary":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","description":"Trigger a full GC. Use to compare heap usage before/after, or to force collection ahead of a heap dump for cleaner output. Causes a pause whose length depends on heap size + collector tuning.","kind":"exec","risk":"medium","side_effects":["Full GC runs.","Pause of seconds on large heaps.","Latency spike during the pause."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":2,"max":4194304}}],"examples":[{"title":"Force GC on a JVM","args":{"pid":12345}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","GC.run"]}},{"id":"jvm.jfr_dump","title":"Dump active JFR recording","summary":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","description":"Dump the active \"emisar\" recording to its current file. Use mid-flight to grab a snapshot without stopping the recording.","kind":"exec","risk":"medium","side_effects":["Writes JFR data to /tmp/<pid>-emisar.jfr.","Recording continues."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Snapshot the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.dump","name=emisar","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_start","title":"Start a Java Flight Recording","summary":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","description":"Start a 60-second Java Flight Recording named \"emisar\". JFR is low-overhead (~1%). Pair with `jvm.jfr_dump` to retrieve the recording, then `jvm.jfr_stop` to end it.","kind":"exec","risk":"medium","side_effects":["Starts a JFR session in the JVM.","Writes profile data to /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}},{"name":"duration","type":"integer","required":false,"default":60,"description":"Duration in seconds.","validation":{"min":10,"max":600}}],"examples":[{"title":"Start a 60s recording","args":{"pid":4321}}],"search_terms":["profiling","cpu profile"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.start","name=emisar","duration={{ args.duration }}s","filename=/tmp/{{ args.pid }}-emisar.jfr"]}},{"id":"jvm.jfr_stop","title":"Stop active JFR recording","summary":"Stop the \"emisar\" recording and finalize the .jfr file.","description":"Stop the \"emisar\" recording and finalize the .jfr file.","kind":"exec","risk":"medium","side_effects":["Stops the recording.","Finalizes /tmp/<pid>-emisar.jfr."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"End the recording","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","JFR.stop","name=emisar"]}},{"id":"jvm.jmap_histo_live","title":"jmap -histo:live (top 50)","summary":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","description":"List top classes by retained-heap size after a forced full GC. Use to find the leak candidate.","kind":"exec","risk":"medium","side_effects":["Triggers a full GC.","JVM pause for the duration of the GC."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Top retained classes","args":{"pid":4321}}],"search_terms":["memory leak"],"command":{"binary":"/bin/sh","argv":["-c","histo=$(jmap -histo:live {{ args.pid }}); status=$?\nprintf '%s\\n' \"$histo\" | head -50\nexit $status\n"]}},{"id":"jvm.jstack","title":"jstack -l (thread dump)","summary":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","description":"Dump full thread state with lock info. The canonical \"what are all my threads doing?\" diagnostic.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only; introduces a STW pause on the JVM (~ms)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread dump","args":{"pid":4321}}],"search_terms":["app hung","threads stuck","app frozen"],"command":{"binary":"jstack","argv":["-l","{{ args.pid }}"]}},{"id":"jvm.jstack_blocked","title":"jstack filtered to BLOCKED threads","summary":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","description":"Run jstack and filter output to threads in BLOCKED state plus their lock owners. Use to find deadlocks fast.","kind":"exec","risk":"low","side_effects":["One jstack invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Find blocked threads","args":{"pid":4321}}],"search_terms":["deadlock","lock contention"],"command":{"binary":"/bin/sh","argv":["-c","jstack -l {{ args.pid }} | awk '/^\"/ {hdr=$0; next} /java.lang.Thread.State: BLOCKED/ {print hdr; print; flag=1; next} flag && /^$/ {flag=0; next} flag {print}'"]}},{"id":"jvm.jstat_class","title":"jstat -class","summary":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","description":"Show class-loader stats — loaded class count and bytes. Use to spot a class-loading leak. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.jmap_histo_live (live-object histogram) or JFR instead.","kind":"exec","risk":"low","side_effects":["One jstat invocation.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Class-load stats","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jstat","argv":["-class","{{ args.pid }}"]}},{"id":"jvm.jstat_gc","title":"jstat -gc (10 samples)","summary":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","description":"Show ten 1-second samples of GC stats. Surfaces young + old GC time, survivor sizes, metaspace usage. Use to spot a GC storm. Needs jvmstat perf data: fails with \"<pid> not found\" on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use jvm.heap_summary for heap state, or JFR (jvm.jfr_start / jvm.jfr_dump) for GC behavior over time.","kind":"exec","risk":"low","side_effects":["One jstat invocation lasting ~10s.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"10-second GC trace","args":{"pid":4321}}],"search_terms":["gc thrashing","gc storm","memory pressure","heap churn"],"command":{"binary":"jstat","argv":["-gc","{{ args.pid }}","1s","10"]}},{"id":"jvm.perfdata","title":"jcmd PerfCounter.print","summary":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","description":"Show JVM performance counters — class loading, JIT, GC. Cheaper than jstat for one-shot. Reads the same jvmstat perf data as jstat: fails on JVMs running -XX:+PerfDisableSharedMem (the Cassandra default) — there use the attach-based reads (jvm.heap_summary, jvm.vm_flags, jvm.jstack) or JFR.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"PerfData","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","PerfCounter.print"]}},{"id":"jvm.thread_count","title":"OS thread count for a JVM","summary":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","description":"Count /proc/<pid>/task entries — fastest way to spot \"do we have an unbounded thread pool?\"","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Thread count","args":{"pid":4321}}],"search_terms":["thread leak"],"command":{"binary":"/bin/sh","argv":["-c","ls /proc/{{ args.pid }}/task | wc -l"]}},{"id":"jvm.vm_flags","title":"jcmd VM.flags","summary":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","description":"Return the JVM command-line and tuning flags. Use to confirm \"is -Xmx set to what we expect?\"","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Flags for PID 4321","args":{"pid":4321}}],"search_terms":["xmx","heap size"],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.flags"]}},{"id":"jvm.vm_system_properties","title":"jcmd VM.system_properties","summary":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()).","description":"Dump every -Dkey=value system property the JVM was started with (jcmd VM.system_properties = System.getProperties()). Use to confirm config overrides took effect — but note this deliberately surfaces every launch -D property, which routinely carries secrets (spring.datasource.password, javax.net.ssl.keyStorePassword, JDBC / cloud credentials). Scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One jcmd call.","Read-only, but exposes every -D launch property (may include secrets)."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"System properties","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.system_properties"]}},{"id":"jvm.vm_uptime","title":"jcmd VM.uptime","summary":"Show how long this JVM has been running.","description":"Show how long this JVM has been running.","kind":"exec","risk":"low","side_effects":["One jcmd call.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"JVM PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"JVM uptime","args":{"pid":4321}}],"search_terms":[],"command":{"binary":"jcmd","argv":["{{ args.pid }}","VM.uptime"]}}]}],"retired_below":"0.1.14"},{"id":"kafka","name":"Kafka cluster operations","version":"0.1.12","description":"Topic introspection, consumer-group lag, broker config, ACLs, and narrow mutators (reset_offsets, alter_topic_retention, delete_consumer_group, preferred_leader_election). Auth via KAFKA_BOOTSTRAP env var on the runner host plus optional KAFKA_COMMAND_CONFIG (jaas / SASL / SSL).","vendor":"emisar","homepage":"https://emisar.dev/packs/kafka","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/kafka","content_hash":"sha256:3b0296d830133afec0a1d612fd8eb166b64a92ca5c295f8b6c6600fcf039263b","tarball_url":"https://registry.emisar.dev/v1/packs/kafka/0.1.12/3b0296d830133afec0a1d612fd8eb166b64a92ca5c295f8b6c6600fcf039263b/pack.tar.gz","requires":{"os":["linux"],"binaries":["kafka-topics.sh"]},"detect":{"binaries":["kafka-topics.sh"],"processes":["kafka.Kafka"],"ports":[9092]},"setup":{"summary":"The kafka-*.sh tools take the broker list from the `KAFKA_BOOTSTRAP` env var on the runner host, which every action passes through as --bootstrap-server.","env":[{"name":"KAFKA_BOOTSTRAP","required":true,"description":"Comma-separated bootstrap broker list (host:port).","example":"broker1:9092,broker2:9092"}],"notes":["`KAFKA_BOOTSTRAP` only reaches an action when the runner allowlists it in `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default. There is NO fallback: unset, every action fails to reach a broker, and the error names a connection problem rather than the missing allowlist entry.","These actions pass only --bootstrap-server — none reference a --command-config / KAFKA_COMMAND_CONFIG properties file, so as written they assume a listener reachable without per-client SASL/TLS credentials.","Mutators (reset_offsets_*, alter_topic_retention, delete_consumer_group, preferred_leader_election) need a principal with cluster/topic/group Alter rights if the cluster enforces ACLs."],"verify":"kafka.cluster_info"},"actions":[{"id":"kafka.alter_topic_retention","title":"Set topic retention.ms","summary":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","description":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","kind":"exec","risk":"high","side_effects":["Old segments past retention will be deleted on next log roll.","Replication lag may briefly spike during cleanup."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}},{"name":"retention_ms","type":"integer","required":true,"description":"New retention.ms.","validation":{"min":60000,"max":31536000000}}],"examples":[{"title":"7-day retention","args":{"retention_ms":604800000,"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--alter' '--entity-type' 'topics' '--entity-name' ''\"$1\"'' '--add-config' 'retention.ms={{ args.retention_ms }}'","emisar","{{ args.topic }}"]}},{"id":"kafka.broker_api_versions","title":"Broker API versions","summary":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","description":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Broker API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-broker-api-versions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\""]}},{"id":"kafka.broker_configs","title":"Broker configs","summary":"List all broker-level configs (dynamic + static + defaults).","description":"List all broker-level configs (dynamic + static + defaults).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"broker_id","type":"string","required":true,"description":"Broker ID (integer as string).","validation":{"pattern":"^[0-9]{1,6}$"}}],"examples":[{"title":"Configs for broker 0","args":{"broker_id":"0"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'brokers' '--entity-name' ''\"$1\"''","emisar","{{ args.broker_id }}"]}},{"id":"kafka.cluster_info","title":"Cluster metadata","summary":"Show broker IDs, controller, cluster ID. Read-only.","description":"Show broker IDs, controller, cluster ID. Read-only.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","info=$(kafka-broker-api-versions.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\"); status=$?\nprintf '%s\\n' \"$info\" | head -50\nexit $status\n"]}},{"id":"kafka.consumer_lag","title":"Consumer lag for a group","summary":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","description":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Lag for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.delete_consumer_group","title":"Delete consumer group","summary":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","description":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","kind":"exec","risk":"high","side_effects":["Group must have no active members; command fails otherwise.","Committed offsets for the group are dropped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Drop empty group","args":{"group":"legacy-consumer"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--delete' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.describe_group","title":"Describe consumer group","summary":"Show member list, partition assignment, host for one consumer group.","description":"Show member list, partition assignment, host for one consumer group.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Describe my-group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--members'","emisar","{{ args.group }}"]}},{"id":"kafka.describe_topic","title":"Describe topic","summary":"Show partition layout, leaders, ISR, replicas for one topic.","description":"Show partition layout, leaders, ISR, replicas for one topic.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Describe my-topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--topic' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.leader_partitions","title":"Partition leaders by broker","summary":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","description":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Leader distribution","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","topics=$(kafka-topics.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\" --describe) || exit 1; printf '%s\\n' \"$topics\" | awk '/Leader/ {match($0,/Leader: [0-9]+/); if (RSTART) print substr($0,RSTART+8,RLENGTH-8)}' | sort | uniq -c"]}},{"id":"kafka.list_acls","title":"List ACLs","summary":"List every ACL binding on the cluster.","description":"List every ACL binding on the cluster.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"All ACLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-acls.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_consumer_offsets","title":"Committed offsets per partition","summary":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","description":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Offsets for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--offsets'","emisar","{{ args.group }}"]}},{"id":"kafka.list_groups","title":"List consumer groups","summary":"List all consumer groups in the cluster.","description":"List all consumer groups in the cluster.","kind":"exec","risk":"low","side_effects":["One coordinator request per broker.","Read-only."],"args":[],"examples":[{"title":"All consumer groups","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_topics","title":"List topics","summary":"List all topics in the cluster.","description":"List all topics in the cluster.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"All topics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.preferred_leader_election","title":"Trigger preferred-leader election","summary":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","description":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","kind":"exec","risk":"high","side_effects":["Brief leadership transitions; in-flight produce/consume may retry.","May cause a temporary spike in metadata churn."],"args":[],"examples":[{"title":"Election across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-leader-election.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--election-type' 'PREFERRED' '--all-topic-partitions'"]}},{"id":"kafka.reassign_status","title":"Partition reassignment status","summary":"Show the status of any in-flight partition reassignments.","description":"Show the status of any in-flight partition reassignments.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"Reassignments in flight","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-reassign-partitions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.reset_offsets_to_earliest","title":"Reset group offsets to earliest","summary":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","description":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","Group will re-process every message in the topic from the beginning."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to reset.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Replay topic from start","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-earliest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.reset_offsets_to_latest","title":"Reset group offsets to latest (skip all)","summary":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","description":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","All unconsumed messages will be skipped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to fast-forward.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Skip backlog","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-latest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.topic_configs","title":"Topic configs","summary":"List topic-level overrides (retention, compaction, segment size).","description":"List topic-level overrides (retention, compaction, segment size).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Configs for one topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'topics' '--entity-name' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.unavailable_partitions","title":"Unavailable partitions","summary":"List partitions with no leader. These mean writes are failing.","description":"List partitions with no leader. These mean writes are failing.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Unavailable partitions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--unavailable-partitions'"]}},{"id":"kafka.under_replicated","title":"Under-replicated partitions","summary":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","description":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"URP across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--under-replicated-partitions'"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:682cfde16f62367a3489c0edb2fd74442ee9a2001890df20f909d3f2b2678792","tarball_url":"https://registry.emisar.dev/v1/packs/kafka/0.1.10/682cfde16f62367a3489c0edb2fd74442ee9a2001890df20f909d3f2b2678792/pack.tar.gz","actions":[{"id":"kafka.alter_topic_retention","title":"Set topic retention.ms","summary":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","description":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","kind":"exec","risk":"high","side_effects":["Old segments past retention will be deleted on next log roll.","Replication lag may briefly spike during cleanup."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}},{"name":"retention_ms","type":"integer","required":true,"description":"New retention.ms.","validation":{"min":60000,"max":31536000000}}],"examples":[{"title":"7-day retention","args":{"retention_ms":604800000,"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--alter' '--entity-type' 'topics' '--entity-name' ''\"$1\"'' '--add-config' 'retention.ms={{ args.retention_ms }}'","emisar","{{ args.topic }}"]}},{"id":"kafka.broker_api_versions","title":"Broker API versions","summary":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","description":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Broker API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-broker-api-versions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\""]}},{"id":"kafka.broker_configs","title":"Broker configs","summary":"List all broker-level configs (dynamic + static + defaults).","description":"List all broker-level configs (dynamic + static + defaults).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"broker_id","type":"string","required":true,"description":"Broker ID (integer as string).","validation":{"pattern":"^[0-9]{1,6}$"}}],"examples":[{"title":"Configs for broker 0","args":{"broker_id":"0"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'brokers' '--entity-name' ''\"$1\"''","emisar","{{ args.broker_id }}"]}},{"id":"kafka.cluster_info","title":"Cluster metadata","summary":"Show broker IDs, controller, cluster ID. Read-only.","description":"Show broker IDs, controller, cluster ID. Read-only.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","info=$(kafka-broker-api-versions.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\"); status=$?\nprintf '%s\\n' \"$info\" | head -50\nexit $status\n"]}},{"id":"kafka.consumer_lag","title":"Consumer lag for a group","summary":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","description":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Lag for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.delete_consumer_group","title":"Delete consumer group","summary":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","description":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","kind":"exec","risk":"high","side_effects":["Group must have no active members; command fails otherwise.","Committed offsets for the group are dropped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Drop empty group","args":{"group":"legacy-consumer"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--delete' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.describe_group","title":"Describe consumer group","summary":"Show member list, partition assignment, host for one consumer group.","description":"Show member list, partition assignment, host for one consumer group.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Describe my-group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--members'","emisar","{{ args.group }}"]}},{"id":"kafka.describe_topic","title":"Describe topic","summary":"Show partition layout, leaders, ISR, replicas for one topic.","description":"Show partition layout, leaders, ISR, replicas for one topic.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Describe my-topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--topic' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.leader_partitions","title":"Partition leaders by broker","summary":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","description":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Leader distribution","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","topics=$(kafka-topics.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\" --describe) || exit 1; printf '%s\\n' \"$topics\" | awk '/Leader/ {match($0,/Leader: [0-9]+/); if (RSTART) print substr($0,RSTART+8,RLENGTH-8)}' | sort | uniq -c"]}},{"id":"kafka.list_acls","title":"List ACLs","summary":"List every ACL binding on the cluster.","description":"List every ACL binding on the cluster.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"All ACLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-acls.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_consumer_offsets","title":"Committed offsets per partition","summary":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","description":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Offsets for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--offsets'","emisar","{{ args.group }}"]}},{"id":"kafka.list_groups","title":"List consumer groups","summary":"List all consumer groups in the cluster.","description":"List all consumer groups in the cluster.","kind":"exec","risk":"low","side_effects":["One coordinator request per broker.","Read-only."],"args":[],"examples":[{"title":"All consumer groups","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_topics","title":"List topics","summary":"List all topics in the cluster.","description":"List all topics in the cluster.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"All topics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.preferred_leader_election","title":"Trigger preferred-leader election","summary":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","description":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","kind":"exec","risk":"high","side_effects":["Brief leadership transitions; in-flight produce/consume may retry.","May cause a temporary spike in metadata churn."],"args":[],"examples":[{"title":"Election across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-leader-election.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--election-type' 'PREFERRED' '--all-topic-partitions'"]}},{"id":"kafka.reassign_status","title":"Partition reassignment status","summary":"Show the status of any in-flight partition reassignments.","description":"Show the status of any in-flight partition reassignments.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"Reassignments in flight","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-reassign-partitions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.reset_offsets_to_earliest","title":"Reset group offsets to earliest","summary":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","description":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","Group will re-process every message in the topic from the beginning."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to reset.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Replay topic from start","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-earliest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.reset_offsets_to_latest","title":"Reset group offsets to latest (skip all)","summary":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","description":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","All unconsumed messages will be skipped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to fast-forward.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Skip backlog","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-latest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.topic_configs","title":"Topic configs","summary":"List topic-level overrides (retention, compaction, segment size).","description":"List topic-level overrides (retention, compaction, segment size).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Configs for one topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'topics' '--entity-name' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.unavailable_partitions","title":"Unavailable partitions","summary":"List partitions with no leader. These mean writes are failing.","description":"List partitions with no leader. These mean writes are failing.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Unavailable partitions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--unavailable-partitions'"]}},{"id":"kafka.under_replicated","title":"Under-replicated partitions","summary":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","description":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"URP across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--under-replicated-partitions'"]}}]},{"version":"0.1.9","content_hash":"sha256:fd9bec0d7342e0e9d3b791a72f6bd818acf6d11285158ee099a0ea536307502c","tarball_url":"https://registry.emisar.dev/v1/packs/kafka/0.1.9/fd9bec0d7342e0e9d3b791a72f6bd818acf6d11285158ee099a0ea536307502c/pack.tar.gz","actions":[{"id":"kafka.alter_topic_retention","title":"Set topic retention.ms","summary":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","description":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","kind":"exec","risk":"high","side_effects":["Old segments past retention will be deleted on next log roll.","Replication lag may briefly spike during cleanup."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}},{"name":"retention_ms","type":"integer","required":true,"description":"New retention.ms.","validation":{"min":60000,"max":31536000000}}],"examples":[{"title":"7-day retention","args":{"retention_ms":604800000,"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--alter' '--entity-type' 'topics' '--entity-name' ''\"$1\"'' '--add-config' 'retention.ms={{ args.retention_ms }}'","emisar","{{ args.topic }}"]}},{"id":"kafka.broker_api_versions","title":"Broker API versions","summary":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","description":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Broker API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-broker-api-versions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\""]}},{"id":"kafka.broker_configs","title":"Broker configs","summary":"List all broker-level configs (dynamic + static + defaults).","description":"List all broker-level configs (dynamic + static + defaults).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"broker_id","type":"string","required":true,"description":"Broker ID (integer as string).","validation":{"pattern":"^[0-9]{1,6}$"}}],"examples":[{"title":"Configs for broker 0","args":{"broker_id":"0"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'brokers' '--entity-name' ''\"$1\"''","emisar","{{ args.broker_id }}"]}},{"id":"kafka.cluster_info","title":"Cluster metadata","summary":"Show broker IDs, controller, cluster ID. Read-only.","description":"Show broker IDs, controller, cluster ID. Read-only.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","info=$(kafka-broker-api-versions.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\"); status=$?\nprintf '%s\\n' \"$info\" | head -50\nexit $status\n"]}},{"id":"kafka.consumer_lag","title":"Consumer lag for a group","summary":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","description":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Lag for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.delete_consumer_group","title":"Delete consumer group","summary":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","description":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","kind":"exec","risk":"high","side_effects":["Group must have no active members; command fails otherwise.","Committed offsets for the group are dropped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Drop empty group","args":{"group":"legacy-consumer"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--delete' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.describe_group","title":"Describe consumer group","summary":"Show member list, partition assignment, host for one consumer group.","description":"Show member list, partition assignment, host for one consumer group.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Describe my-group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--members'","emisar","{{ args.group }}"]}},{"id":"kafka.describe_topic","title":"Describe topic","summary":"Show partition layout, leaders, ISR, replicas for one topic.","description":"Show partition layout, leaders, ISR, replicas for one topic.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Describe my-topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--topic' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.leader_partitions","title":"Partition leaders by broker","summary":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","description":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Leader distribution","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","topics=$(kafka-topics.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\" --describe) || exit 1; printf '%s\\n' \"$topics\" | awk '/Leader/ {match($0,/Leader: [0-9]+/); if (RSTART) print substr($0,RSTART+8,RLENGTH-8)}' | sort | uniq -c"]}},{"id":"kafka.list_acls","title":"List ACLs","summary":"List every ACL binding on the cluster.","description":"List every ACL binding on the cluster.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"All ACLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-acls.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_consumer_offsets","title":"Committed offsets per partition","summary":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","description":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Offsets for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--offsets'","emisar","{{ args.group }}"]}},{"id":"kafka.list_groups","title":"List consumer groups","summary":"List all consumer groups in the cluster.","description":"List all consumer groups in the cluster.","kind":"exec","risk":"low","side_effects":["One coordinator request per broker.","Read-only."],"args":[],"examples":[{"title":"All consumer groups","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_topics","title":"List topics","summary":"List all topics in the cluster.","description":"List all topics in the cluster.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"All topics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.preferred_leader_election","title":"Trigger preferred-leader election","summary":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","description":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","kind":"exec","risk":"high","side_effects":["Brief leadership transitions; in-flight produce/consume may retry.","May cause a temporary spike in metadata churn."],"args":[],"examples":[{"title":"Election across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-leader-election.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--election-type' 'PREFERRED' '--all-topic-partitions'"]}},{"id":"kafka.reassign_status","title":"Partition reassignment status","summary":"Show the status of any in-flight partition reassignments.","description":"Show the status of any in-flight partition reassignments.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"Reassignments in flight","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-reassign-partitions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.reset_offsets_to_earliest","title":"Reset group offsets to earliest","summary":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","description":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","Group will re-process every message in the topic from the beginning."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to reset.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Replay topic from start","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-earliest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.reset_offsets_to_latest","title":"Reset group offsets to latest (skip all)","summary":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","description":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","All unconsumed messages will be skipped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to fast-forward.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Skip backlog","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-latest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.topic_configs","title":"Topic configs","summary":"List topic-level overrides (retention, compaction, segment size).","description":"List topic-level overrides (retention, compaction, segment size).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Configs for one topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'topics' '--entity-name' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.unavailable_partitions","title":"Unavailable partitions","summary":"List partitions with no leader. These mean writes are failing.","description":"List partitions with no leader. These mean writes are failing.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Unavailable partitions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--unavailable-partitions'"]}},{"id":"kafka.under_replicated","title":"Under-replicated partitions","summary":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","description":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"URP across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--under-replicated-partitions'"]}}]},{"version":"0.1.7","content_hash":"sha256:4ff3c03655664d4767a129d3eb0aee3cb448645ad904ec2fbc9f1d9e89358a7d","tarball_url":"https://registry.emisar.dev/v1/packs/kafka/0.1.7/4ff3c03655664d4767a129d3eb0aee3cb448645ad904ec2fbc9f1d9e89358a7d/pack.tar.gz","actions":[{"id":"kafka.alter_topic_retention","title":"Set topic retention.ms","summary":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","description":"Set `retention.ms` on a topic. Lower values cause old data to be deleted in the next log roll.","kind":"exec","risk":"high","side_effects":["Old segments past retention will be deleted on next log roll.","Replication lag may briefly spike during cleanup."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}},{"name":"retention_ms","type":"integer","required":true,"description":"New retention.ms.","validation":{"min":60000,"max":31536000000}}],"examples":[{"title":"7-day retention","args":{"retention_ms":604800000,"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--alter' '--entity-type' 'topics' '--entity-name' ''\"$1\"'' '--add-config' 'retention.ms={{ args.retention_ms }}'","emisar","{{ args.topic }}"]}},{"id":"kafka.broker_api_versions","title":"Broker API versions","summary":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","description":"Show the API protocol versions supported by each broker. Useful to confirm rolling upgrade.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Broker API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-broker-api-versions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\""]}},{"id":"kafka.broker_configs","title":"Broker configs","summary":"List all broker-level configs (dynamic + static + defaults).","description":"List all broker-level configs (dynamic + static + defaults).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"broker_id","type":"string","required":true,"description":"Broker ID (integer as string).","validation":{"pattern":"^[0-9]{1,6}$"}}],"examples":[{"title":"Configs for broker 0","args":{"broker_id":"0"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'brokers' '--entity-name' ''\"$1\"''","emisar","{{ args.broker_id }}"]}},{"id":"kafka.cluster_info","title":"Cluster metadata","summary":"Show broker IDs, controller, cluster ID. Read-only.","description":"Show broker IDs, controller, cluster ID. Read-only.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","info=$(kafka-broker-api-versions.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\"); status=$?\nprintf '%s\\n' \"$info\" | head -50\nexit $status\n"]}},{"id":"kafka.consumer_lag","title":"Consumer lag for a group","summary":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","description":"Show per-partition lag (log-end-offset minus committed offset) for one consumer group. The canonical \"is consumption keeping up?\" check.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Lag for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.delete_consumer_group","title":"Delete consumer group","summary":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","description":"Remove a consumer group from the coordinator; its committed offsets are permanently dropped, so a re-created group restarts from auto.offset.reset. The group must be empty (no active members).","kind":"exec","risk":"high","side_effects":["Group must have no active members; command fails otherwise.","Committed offsets for the group are dropped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Drop empty group","args":{"group":"legacy-consumer"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--delete' '--group' ''\"$1\"''","emisar","{{ args.group }}"]}},{"id":"kafka.describe_group","title":"Describe consumer group","summary":"Show member list, partition assignment, host for one consumer group.","description":"Show member list, partition assignment, host for one consumer group.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Describe my-group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--members'","emisar","{{ args.group }}"]}},{"id":"kafka.describe_topic","title":"Describe topic","summary":"Show partition layout, leaders, ISR, replicas for one topic.","description":"Show partition layout, leaders, ISR, replicas for one topic.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Describe my-topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--topic' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.leader_partitions","title":"Partition leaders by broker","summary":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","description":"Count partitions where each broker is leader. Uneven distribution → preferred-leader election.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Leader distribution","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh --bootstrap-server \"$KAFKA_BOOTSTRAP\" --describe | awk '/Leader/ {match($0,/Leader: [0-9]+/); if (RSTART) print substr($0,RSTART+8,RLENGTH-8)}' | sort | uniq -c"]}},{"id":"kafka.list_acls","title":"List ACLs","summary":"List every ACL binding on the cluster.","description":"List every ACL binding on the cluster.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"All ACLs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-acls.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_consumer_offsets","title":"Committed offsets per partition","summary":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","description":"Show the same view as consumer_lag but emphasizes committed-offset reading. Useful before reset_offsets.","kind":"exec","risk":"low","side_effects":["One coordinator request.","Read-only."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}}],"examples":[{"title":"Offsets for one group","args":{"group":"order-processor"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--group' ''\"$1\"'' '--offsets'","emisar","{{ args.group }}"]}},{"id":"kafka.list_groups","title":"List consumer groups","summary":"List all consumer groups in the cluster.","description":"List all consumer groups in the cluster.","kind":"exec","risk":"low","side_effects":["One coordinator request per broker.","Read-only."],"args":[],"examples":[{"title":"All consumer groups","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.list_topics","title":"List topics","summary":"List all topics in the cluster.","description":"List all topics in the cluster.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"All topics","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.preferred_leader_election","title":"Trigger preferred-leader election","summary":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","description":"Force preferred-leader election cluster-wide. Use after a broker restart leaves leaders skewed.","kind":"exec","risk":"high","side_effects":["Brief leadership transitions; in-flight produce/consume may retry.","May cause a temporary spike in metadata churn."],"args":[],"examples":[{"title":"Election across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-leader-election.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--election-type' 'PREFERRED' '--all-topic-partitions'"]}},{"id":"kafka.reassign_status","title":"Partition reassignment status","summary":"Show the status of any in-flight partition reassignments.","description":"Show the status of any in-flight partition reassignments.","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[],"examples":[{"title":"Reassignments in flight","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-reassign-partitions.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--list'"]}},{"id":"kafka.reset_offsets_to_earliest","title":"Reset group offsets to earliest","summary":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","description":"Rewind a consumer group's offsets to the start of every partition. Causes a full replay — can be hours to days of duplicate processing.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","Group will re-process every message in the topic from the beginning."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to reset.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Replay topic from start","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-earliest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.reset_offsets_to_latest","title":"Reset group offsets to latest (skip all)","summary":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","description":"Fast-forward a consumer group past every existing message — they will NOT be processed. Data loss for that consumer.","kind":"exec","risk":"critical","side_effects":["Consumer group must be stopped first; this command fails if still active.","All unconsumed messages will be skipped."],"args":[{"name":"group","type":"string","required":true,"description":"Consumer group ID.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,255}$"}},{"name":"topic","type":"string","required":true,"description":"Topic to fast-forward.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Skip backlog","args":{"group":"order-processor","topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-consumer-groups.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--group' ''\"$1\"'' '--topic' ''\"$2\"'' '--reset-offsets' '--to-latest' '--execute'","emisar","{{ args.group }}","{{ args.topic }}"]}},{"id":"kafka.topic_configs","title":"Topic configs","summary":"List topic-level overrides (retention, compaction, segment size).","description":"List topic-level overrides (retention, compaction, segment size).","kind":"exec","risk":"low","side_effects":["One admin request.","Read-only."],"args":[{"name":"topic","type":"string","required":true,"description":"Topic name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,249}$"}}],"examples":[{"title":"Configs for one topic","args":{"topic":"orders"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-configs.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--entity-type' 'topics' '--entity-name' ''\"$1\"''","emisar","{{ args.topic }}"]}},{"id":"kafka.unavailable_partitions","title":"Unavailable partitions","summary":"List partitions with no leader. These mean writes are failing.","description":"List partitions with no leader. These mean writes are failing.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"Unavailable partitions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--unavailable-partitions'"]}},{"id":"kafka.under_replicated","title":"Under-replicated partitions","summary":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","description":"List topics + partitions with ISR < replication factor. The canonical \"is replication healthy?\" check.","kind":"exec","risk":"low","side_effects":["One metadata request.","Read-only."],"args":[],"examples":[{"title":"URP across cluster","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kafka-topics.sh '--bootstrap-server' \"$KAFKA_BOOTSTRAP\" '--describe' '--under-replicated-partitions'"]}}]}]},{"id":"kubernetes","name":"Kubernetes operations pack","version":"0.2.9","description":"Operator pack for Kubernetes clusters: discovery (pods, nodes, services, deployments), deep introspection (describe, logs, events), rollouts (status, history, restart, undo), and narrow node/pod mutators (cordon, drain, delete). Cluster targeting via KUBECONFIG env var on the runner host; context selectable per call.","vendor":"emisar","homepage":"https://emisar.dev/packs/kubernetes","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/kubernetes","content_hash":"sha256:bc1e0123339ac07474f2c7aae9983fc89e943eb3d5f50201a9c9d6c55c455405","tarball_url":"https://registry.emisar.dev/v1/packs/kubernetes/0.2.9/bc1e0123339ac07474f2c7aae9983fc89e943eb3d5f50201a9c9d6c55c455405/pack.tar.gz","requires":{"os":["linux"],"binaries":["kubectl"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"kubectl finds the cluster and credentials from a kubeconfig on the runner host. Point it at one with `KUBECONFIG`, or rely on the default `~/.kube/config`. Each action takes an optional context argument.","env":[{"name":"KUBECONFIG","description":"Path (or colon-separated paths) to the kubeconfig file. Omit to use the default `~/.kube/config`.","example":"/etc/emisar/kubeconfig"}],"notes":["If `KUBECONFIG` is unset, kubectl reads `~/.kube/config` on the runner host — a file, so it needs no `inherit_env` entry.","The kubeconfig must embed working credentials (client cert, token, or an exec auth plugin); whatever identity it carries gates which actions succeed, and mutators (cordon, drain, delete_pod) need RBAC for those verbs. Use auth_can_i to confirm what the identity may do.","RKE2: point `KUBECONFIG` at `/etc/rancher/rke2/rke2.yaml` on a server node (root-readable, mode 0600); for a remote runner rewrite its 127.0.0.1:6443 server URL to a reachable address. RKE2 does not bundle metrics-server, so nodes_top / pods_top error until one is installed. RKE2 host/etcd/containerd specifics live in the separate rke2 pack."],"verify":"kubernetes.cluster_info"},"actions":[{"id":"kubernetes.api_versions","title":"kubectl api-versions","summary":"List API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","description":"List API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","kind":"exec","risk":"low","side_effects":["One kubectl api-versions invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} api-versions"]}},{"id":"kubernetes.auth_can_i","title":"List my RBAC permissions (auth can-i --list)","summary":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","description":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl auth can-i invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Namespace to scope to. Empty = current/default.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All my permissions","args":{}},{"title":"In one namespace","args":{"namespace":"kube-system"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} ${NS:+-n $NS} auth can-i --list"]}},{"id":"kubernetes.cluster_info","title":"kubectl cluster-info","summary":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","description":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","kind":"exec","risk":"low","side_effects":["One kubectl cluster-info invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cluster-info"]}},{"id":"kubernetes.control_plane_health","title":"Control-plane readiness (/readyz?verbose)","summary":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","description":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get --raw invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Control-plane readiness","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get --raw '/readyz?verbose'"]}},{"id":"kubernetes.cordon","title":"kubectl cordon node","summary":"Mark a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","description":"Mark a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","kind":"exec","risk":"high","side_effects":["Node marked unschedulable.","Existing pods unaffected; new pods routed elsewhere."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cordon \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.crds_list","title":"List CustomResourceDefinitions","summary":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","description":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All CRDs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get crd"]}},{"id":"kubernetes.cronjobs_list","title":"List CronJobs across all namespaces","summary":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","description":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All cronjobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get cronjobs -A"]}},{"id":"kubernetes.daemonsets_list","title":"List daemonsets","summary":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","description":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All daemonsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ds -A"]}},{"id":"kubernetes.delete_pod","title":"Delete one pod (force-restart-by-killing)","summary":"Delete one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","description":"Delete one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","kind":"exec","risk":"high","side_effects":["Pod sent SIGTERM, then SIGKILL after terminationGracePeriodSeconds.","Controller recreates the pod unless it was a standalone Pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name (no wildcards).","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Delete a stuck pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" delete pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.deployments_list","title":"List deployments","summary":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","description":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All deployments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get deploy -A"]}},{"id":"kubernetes.drain","title":"kubectl drain node (cordon + evict)","summary":"Cordon the node and evict every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","description":"Cordon the node and evict every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","kind":"exec","risk":"critical","side_effects":["Node marked unschedulable.","Every controller-managed pod evicted; recreated elsewhere.","emptyDir volumes on this node are lost."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Drain one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} drain \"$1\" --ignore-daemonsets --delete-emptydir-data","emisar","{{ args.name }}"]}},{"id":"kubernetes.endpoints_list","title":"List endpoints across all namespaces","summary":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","description":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All endpoints","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get endpoints -A"]}},{"id":"kubernetes.events_for_pod","title":"Events for one pod","summary":"List field-selected events that reference one pod.","description":"List field-selected events that reference one pod.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Events for one pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get events --field-selector involvedObject.kind=Pod,involvedObject.name=\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.events_recent","title":"Recent cluster events","summary":"List the last 50 events across all namespaces, sorted by last timestamp.","description":"List the last 50 events across all namespaces, sorted by last timestamp.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Recent events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -50\nexit $status\n"]}},{"id":"kubernetes.events_warnings","title":"Recent Warning events (all namespaces)","summary":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","description":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Warning events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --field-selector type=Warning --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -n 60\nexit $status\n"]}},{"id":"kubernetes.get_yaml","title":"Get resource YAML","summary":"Return the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","description":"Return the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":true,"description":"Resource kind.","validation":{"enum":["pod","deployment","statefulset","daemonset","service","ingress","pvc","hpa","cronjob","job"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"YAML of one deployment","args":{"kind":"deployment","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get {{ args.kind }}/\"$2\" -o yaml","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.hpa_list","title":"List HorizontalPodAutoscalers","summary":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","description":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All HPAs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get hpa -A"]}},{"id":"kubernetes.ingresses_list","title":"List ingresses across all namespaces","summary":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","description":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All ingresses","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ingress -A"]}},{"id":"kubernetes.jobs_list","title":"List Jobs across all namespaces","summary":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","description":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All jobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get jobs -A"]}},{"id":"kubernetes.namespaces","title":"List namespaces","summary":"`kubectl get ns` — every namespace with status + age.","description":"`kubectl get ns` — every namespace with status + age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ns"]}},{"id":"kubernetes.networkpolicies_list","title":"List NetworkPolicies across all namespaces","summary":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","description":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All network policies","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get networkpolicies -A"]}},{"id":"kubernetes.node_describe","title":"kubectl describe node","summary":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","description":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} describe node \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.nodes_list","title":"List cluster nodes","summary":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","description":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get nodes -o wide --show-labels"]}},{"id":"kubernetes.nodes_top","title":"Nodes by CPU + memory","summary":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","description":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Node utilization","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} top nodes"]}},{"id":"kubernetes.pod_describe","title":"kubectl describe pod","summary":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","description":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" describe pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_logs","title":"Tail pod logs","summary":"Tail the last N lines from one container in a pod.","description":"Tail the last N lines from one container in a pod.","kind":"exec","risk":"medium","side_effects":["One kubectl logs invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default container).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last 200 lines","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_previous_logs","title":"Tail PREVIOUS container logs (crash debug)","summary":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","description":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","kind":"exec","risk":"medium","side_effects":["One kubectl logs invocation with --previous.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last logs from a crashed container","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --previous --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pods_list","title":"List pods across all namespaces","summary":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","description":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context to use. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A -o wide"]}},{"id":"kubernetes.pods_problem","title":"Pods NOT in Running/Succeeded","summary":"Filter pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","description":"Filter pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Show problem pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded -o wide"]}},{"id":"kubernetes.pods_top","title":"Pods by CPU (metrics-server)","summary":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","description":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Top CPU consumers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","pods=$(kubectl ${KCTX:+--context=$KCTX} top pod -A --sort-by=cpu); status=$?\nprintf '%s\\n' \"$pods\" | head -50\nexit $status\n"]}},{"id":"kubernetes.pv_list","title":"List PersistentVolumes","summary":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","description":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All persistent volumes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pv"]}},{"id":"kubernetes.pvcs_list","title":"List PVCs across all namespaces","summary":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","description":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All PVCs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pvc -A"]}},{"id":"kubernetes.quotas_list","title":"ResourceQuota + LimitRange for a namespace","summary":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","description":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace to inspect.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Quotas in a namespace","args":{"namespace":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n $NS get resourcequota,limitrange"]}},{"id":"kubernetes.rollout_history","title":"kubectl rollout history","summary":"Return the revision history for a deployment / statefulset / daemonset.","description":"Return the revision history for a deployment / statefulset / daemonset.","kind":"exec","risk":"low","side_effects":["One kubectl rollout history invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"History for one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout history {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_restart","title":"kubectl rollout restart (rolling)","summary":"Trigger a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","description":"Trigger a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout of the resource.","Pods are replaced one-by-one; in-flight requests are drained per pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rolling restart of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout restart {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_status","title":"kubectl rollout status","summary":"Report the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","description":"Report the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","kind":"exec","risk":"low","side_effects":["One kubectl rollout status invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Status of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout status {{ args.kind }}/\"$2\" --watch=false","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_undo","title":"kubectl rollout undo (rollback)","summary":"Roll back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","description":"Roll back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout to the previous revision.","Pods replaced one-by-one; previous container image becomes current."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rollback the api deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout undo {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.scale_deployment","title":"Scale a deployment","summary":"Set deployment replica count; 0 stops every pod and takes the workload offline. Use to scale up before a traffic event or scale down to drain.","description":"Set deployment replica count; 0 stops every pod and takes the workload offline. Use to scale up before a traffic event or scale down to drain.","kind":"exec","risk":"high","side_effects":["Triggers scale up/down.","Pods created or terminated to reach the target replica count."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"replicas","type":"integer","required":true,"description":"Target replica count.","validation":{"min":0,"max":1000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Scale api to 10 replicas","args":{"name":"api","namespace":"default","replicas":10}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" scale deploy/\"$2\" --replicas={{ args.replicas }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.services_list","title":"List services across all namespaces","summary":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","description":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get svc -A"]}},{"id":"kubernetes.set_image","title":"Set deployment container image","summary":"Update one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","description":"Update one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","kind":"exec","risk":"high","side_effects":["Updates the deployment spec.","Triggers a rolling update; pods replaced one-by-one."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":true,"description":"Container name (from the pod spec).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"image","type":"string","required":true,"description":"Image ref (repository:tag).","validation":{"pattern":"^[a-zA-Z0-9_./@:\\-]{1,256}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Update api to a new image","args":{"container":"api","image":"ghcr.io/example/api:v1.42.0","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" set image deploy/\"$2\" \"$3\"=\"$4\"","emisar","{{ args.namespace }}","{{ args.name }}","{{ args.container }}","{{ args.image }}"]}},{"id":"kubernetes.statefulsets_list","title":"List statefulsets","summary":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","description":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All statefulsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get sts -A"]}},{"id":"kubernetes.storageclasses_list","title":"List StorageClasses","summary":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","description":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All storage classes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get storageclass"]}},{"id":"kubernetes.uncordon","title":"kubectl uncordon node","summary":"Mark a node schedulable again. Reverse of cordon.","description":"Mark a node schedulable again. Reverse of cordon.","kind":"exec","risk":"medium","side_effects":["Node marked schedulable.","New pods may schedule onto it."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Uncordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} uncordon \"$1\"","emisar","{{ args.name }}"]}}],"previous_versions":[{"version":"0.2.8","content_hash":"sha256:83e6affa60c99d2914490270340e78ffe29c6f2be0410197742f4e13c4b832a5","tarball_url":"https://registry.emisar.dev/v1/packs/kubernetes/0.2.8/83e6affa60c99d2914490270340e78ffe29c6f2be0410197742f4e13c4b832a5/pack.tar.gz","actions":[{"id":"kubernetes.api_versions","title":"kubectl api-versions","summary":"List API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","description":"List API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","kind":"exec","risk":"low","side_effects":["One kubectl api-versions invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} api-versions"]}},{"id":"kubernetes.auth_can_i","title":"List my RBAC permissions (auth can-i --list)","summary":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","description":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl auth can-i invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Namespace to scope to. Empty = current/default.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All my permissions","args":{}},{"title":"In one namespace","args":{"namespace":"kube-system"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} ${NS:+-n $NS} auth can-i --list"]}},{"id":"kubernetes.cluster_info","title":"kubectl cluster-info","summary":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","description":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","kind":"exec","risk":"low","side_effects":["One kubectl cluster-info invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cluster-info"]}},{"id":"kubernetes.control_plane_health","title":"Control-plane readiness (/readyz?verbose)","summary":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","description":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get --raw invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Control-plane readiness","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get --raw '/readyz?verbose'"]}},{"id":"kubernetes.cordon","title":"kubectl cordon node","summary":"Mark a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","description":"Mark a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","kind":"exec","risk":"high","side_effects":["Node marked unschedulable.","Existing pods unaffected; new pods routed elsewhere."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cordon \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.crds_list","title":"List CustomResourceDefinitions","summary":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","description":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All CRDs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get crd"]}},{"id":"kubernetes.cronjobs_list","title":"List CronJobs across all namespaces","summary":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","description":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All cronjobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get cronjobs -A"]}},{"id":"kubernetes.daemonsets_list","title":"List daemonsets","summary":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","description":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All daemonsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ds -A"]}},{"id":"kubernetes.delete_pod","title":"Delete one pod (force-restart-by-killing)","summary":"Delete one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","description":"Delete one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","kind":"exec","risk":"high","side_effects":["Pod sent SIGTERM, then SIGKILL after terminationGracePeriodSeconds.","Controller recreates the pod unless it was a standalone Pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name (no wildcards).","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Delete a stuck pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" delete pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.deployments_list","title":"List deployments","summary":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","description":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All deployments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get deploy -A"]}},{"id":"kubernetes.drain","title":"kubectl drain node (cordon + evict)","summary":"Cordon the node and evict every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","description":"Cordon the node and evict every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","kind":"exec","risk":"critical","side_effects":["Node marked unschedulable.","Every controller-managed pod evicted; recreated elsewhere.","emptyDir volumes on this node are lost."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Drain one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} drain \"$1\" --ignore-daemonsets --delete-emptydir-data","emisar","{{ args.name }}"]}},{"id":"kubernetes.endpoints_list","title":"List endpoints across all namespaces","summary":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","description":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All endpoints","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get endpoints -A"]}},{"id":"kubernetes.events_for_pod","title":"Events for one pod","summary":"List field-selected events that reference one pod.","description":"List field-selected events that reference one pod.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Events for one pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get events --field-selector involvedObject.kind=Pod,involvedObject.name=\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.events_recent","title":"Recent cluster events","summary":"List the last 50 events across all namespaces, sorted by last timestamp.","description":"List the last 50 events across all namespaces, sorted by last timestamp.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Recent events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -50\nexit $status\n"]}},{"id":"kubernetes.events_warnings","title":"Recent Warning events (all namespaces)","summary":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","description":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Warning events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --field-selector type=Warning --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -n 60\nexit $status\n"]}},{"id":"kubernetes.get_yaml","title":"Get resource YAML","summary":"Return the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","description":"Return the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":true,"description":"Resource kind.","validation":{"enum":["pod","deployment","statefulset","daemonset","service","ingress","pvc","hpa","cronjob","job"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"YAML of one deployment","args":{"kind":"deployment","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get {{ args.kind }}/\"$2\" -o yaml","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.hpa_list","title":"List HorizontalPodAutoscalers","summary":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","description":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All HPAs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get hpa -A"]}},{"id":"kubernetes.ingresses_list","title":"List ingresses across all namespaces","summary":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","description":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All ingresses","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ingress -A"]}},{"id":"kubernetes.jobs_list","title":"List Jobs across all namespaces","summary":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","description":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All jobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get jobs -A"]}},{"id":"kubernetes.namespaces","title":"List namespaces","summary":"`kubectl get ns` — every namespace with status + age.","description":"`kubectl get ns` — every namespace with status + age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ns"]}},{"id":"kubernetes.networkpolicies_list","title":"List NetworkPolicies across all namespaces","summary":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","description":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All network policies","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get networkpolicies -A"]}},{"id":"kubernetes.node_describe","title":"kubectl describe node","summary":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","description":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} describe node \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.nodes_list","title":"List cluster nodes","summary":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","description":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get nodes -o wide --show-labels"]}},{"id":"kubernetes.nodes_top","title":"Nodes by CPU + memory","summary":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","description":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Node utilization","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} top nodes"]}},{"id":"kubernetes.pod_describe","title":"kubectl describe pod","summary":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","description":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" describe pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_logs","title":"Tail pod logs","summary":"Tail the last N lines from one container in a pod.","description":"Tail the last N lines from one container in a pod.","kind":"exec","risk":"low","side_effects":["One kubectl logs invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default container).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last 200 lines","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_previous_logs","title":"Tail PREVIOUS container logs (crash debug)","summary":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","description":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","kind":"exec","risk":"low","side_effects":["One kubectl logs invocation with --previous.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last logs from a crashed container","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --previous --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pods_list","title":"List pods across all namespaces","summary":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","description":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context to use. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A -o wide"]}},{"id":"kubernetes.pods_problem","title":"Pods NOT in Running/Succeeded","summary":"Filter pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","description":"Filter pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Show problem pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded -o wide"]}},{"id":"kubernetes.pods_top","title":"Pods by CPU (metrics-server)","summary":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","description":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Top CPU consumers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","pods=$(kubectl ${KCTX:+--context=$KCTX} top pod -A --sort-by=cpu); status=$?\nprintf '%s\\n' \"$pods\" | head -50\nexit $status\n"]}},{"id":"kubernetes.pv_list","title":"List PersistentVolumes","summary":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","description":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All persistent volumes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pv"]}},{"id":"kubernetes.pvcs_list","title":"List PVCs across all namespaces","summary":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","description":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All PVCs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pvc -A"]}},{"id":"kubernetes.quotas_list","title":"ResourceQuota + LimitRange for a namespace","summary":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","description":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace to inspect.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Quotas in a namespace","args":{"namespace":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n $NS get resourcequota,limitrange"]}},{"id":"kubernetes.rollout_history","title":"kubectl rollout history","summary":"Return the revision history for a deployment / statefulset / daemonset.","description":"Return the revision history for a deployment / statefulset / daemonset.","kind":"exec","risk":"low","side_effects":["One kubectl rollout history invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"History for one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout history {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_restart","title":"kubectl rollout restart (rolling)","summary":"Trigger a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","description":"Trigger a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout of the resource.","Pods are replaced one-by-one; in-flight requests are drained per pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rolling restart of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout restart {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_status","title":"kubectl rollout status","summary":"Report the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","description":"Report the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","kind":"exec","risk":"low","side_effects":["One kubectl rollout status invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Status of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout status {{ args.kind }}/\"$2\" --watch=false","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_undo","title":"kubectl rollout undo (rollback)","summary":"Roll back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","description":"Roll back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout to the previous revision.","Pods replaced one-by-one; previous container image becomes current."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rollback the api deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout undo {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.scale_deployment","title":"Scale a deployment","summary":"Set deployment replica count; 0 stops every pod and takes the workload offline. Use to scale up before a traffic event or scale down to drain.","description":"Set deployment replica count; 0 stops every pod and takes the workload offline. Use to scale up before a traffic event or scale down to drain.","kind":"exec","risk":"high","side_effects":["Triggers scale up/down.","Pods created or terminated to reach the target replica count."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"replicas","type":"integer","required":true,"description":"Target replica count.","validation":{"min":0,"max":1000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Scale api to 10 replicas","args":{"name":"api","namespace":"default","replicas":10}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" scale deploy/\"$2\" --replicas={{ args.replicas }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.services_list","title":"List services across all namespaces","summary":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","description":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get svc -A"]}},{"id":"kubernetes.set_image","title":"Set deployment container image","summary":"Update one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","description":"Update one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","kind":"exec","risk":"high","side_effects":["Updates the deployment spec.","Triggers a rolling update; pods replaced one-by-one."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":true,"description":"Container name (from the pod spec).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"image","type":"string","required":true,"description":"Image ref (repository:tag).","validation":{"pattern":"^[a-zA-Z0-9_./@:\\-]{1,256}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Update api to a new image","args":{"container":"api","image":"ghcr.io/example/api:v1.42.0","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" set image deploy/\"$2\" \"$3\"=\"$4\"","emisar","{{ args.namespace }}","{{ args.name }}","{{ args.container }}","{{ args.image }}"]}},{"id":"kubernetes.statefulsets_list","title":"List statefulsets","summary":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","description":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All statefulsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get sts -A"]}},{"id":"kubernetes.storageclasses_list","title":"List StorageClasses","summary":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","description":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All storage classes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get storageclass"]}},{"id":"kubernetes.uncordon","title":"kubectl uncordon node","summary":"Mark a node schedulable again. Reverse of cordon.","description":"Mark a node schedulable again. Reverse of cordon.","kind":"exec","risk":"medium","side_effects":["Node marked schedulable.","New pods may schedule onto it."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Uncordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} uncordon \"$1\"","emisar","{{ args.name }}"]}}]},{"version":"0.2.5","content_hash":"sha256:a119ddd72d78b2f9771f63950b97418ad97edda5e059e6bb84a100ef18c976b1","tarball_url":"https://registry.emisar.dev/v1/packs/kubernetes/0.2.5/a119ddd72d78b2f9771f63950b97418ad97edda5e059e6bb84a100ef18c976b1/pack.tar.gz","actions":[{"id":"kubernetes.api_versions","title":"kubectl api-versions","summary":"List API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","description":"List API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","kind":"exec","risk":"low","side_effects":["One kubectl api-versions invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} api-versions"]}},{"id":"kubernetes.auth_can_i","title":"List my RBAC permissions (auth can-i --list)","summary":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","description":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl auth can-i invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Namespace to scope to. Empty = current/default.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All my permissions","args":{}},{"title":"In one namespace","args":{"namespace":"kube-system"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} ${NS:+-n $NS} auth can-i --list"]}},{"id":"kubernetes.cluster_info","title":"kubectl cluster-info","summary":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","description":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","kind":"exec","risk":"low","side_effects":["One kubectl cluster-info invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cluster-info"]}},{"id":"kubernetes.control_plane_health","title":"Control-plane readiness (/readyz?verbose)","summary":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","description":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get --raw invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Control-plane readiness","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get --raw '/readyz?verbose'"]}},{"id":"kubernetes.cordon","title":"kubectl cordon node","summary":"Mark a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","description":"Mark a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","kind":"exec","risk":"high","side_effects":["Node marked unschedulable.","Existing pods unaffected; new pods routed elsewhere."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cordon \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.crds_list","title":"List CustomResourceDefinitions","summary":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","description":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All CRDs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get crd"]}},{"id":"kubernetes.cronjobs_list","title":"List CronJobs across all namespaces","summary":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","description":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All cronjobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get cronjobs -A"]}},{"id":"kubernetes.daemonsets_list","title":"List daemonsets","summary":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","description":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All daemonsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ds -A"]}},{"id":"kubernetes.delete_pod","title":"Delete one pod (force-restart-by-killing)","summary":"Delete one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","description":"Delete one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","kind":"exec","risk":"high","side_effects":["Pod sent SIGTERM, then SIGKILL after terminationGracePeriodSeconds.","Controller recreates the pod unless it was a standalone Pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name (no wildcards).","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Delete a stuck pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" delete pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.deployments_list","title":"List deployments","summary":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","description":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All deployments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get deploy -A"]}},{"id":"kubernetes.drain","title":"kubectl drain node (cordon + evict)","summary":"Cordon the node and evict every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","description":"Cordon the node and evict every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","kind":"exec","risk":"critical","side_effects":["Node marked unschedulable.","Every controller-managed pod evicted; recreated elsewhere.","emptyDir volumes on this node are lost."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Drain one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} drain \"$1\" --ignore-daemonsets --delete-emptydir-data","emisar","{{ args.name }}"]}},{"id":"kubernetes.endpoints_list","title":"List endpoints across all namespaces","summary":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","description":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All endpoints","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get endpoints -A"]}},{"id":"kubernetes.events_for_pod","title":"Events for one pod","summary":"List field-selected events that reference one pod.","description":"List field-selected events that reference one pod.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Events for one pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get events --field-selector involvedObject.kind=Pod,involvedObject.name=\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.events_recent","title":"Recent cluster events","summary":"List the last 50 events across all namespaces, sorted by last timestamp.","description":"List the last 50 events across all namespaces, sorted by last timestamp.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Recent events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -50\nexit $status\n"]}},{"id":"kubernetes.events_warnings","title":"Recent Warning events (all namespaces)","summary":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","description":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Warning events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --field-selector type=Warning --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -n 60\nexit $status\n"]}},{"id":"kubernetes.get_yaml","title":"Get resource YAML","summary":"Return the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","description":"Return the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":true,"description":"Resource kind.","validation":{"enum":["pod","deployment","statefulset","daemonset","service","ingress","pvc","hpa","cronjob","job"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"YAML of one deployment","args":{"kind":"deployment","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get {{ args.kind }}/\"$2\" -o yaml","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.hpa_list","title":"List HorizontalPodAutoscalers","summary":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","description":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All HPAs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get hpa -A"]}},{"id":"kubernetes.ingresses_list","title":"List ingresses across all namespaces","summary":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","description":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All ingresses","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ingress -A"]}},{"id":"kubernetes.jobs_list","title":"List Jobs across all namespaces","summary":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","description":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All jobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get jobs -A"]}},{"id":"kubernetes.namespaces","title":"List namespaces","summary":"`kubectl get ns` — every namespace with status + age.","description":"`kubectl get ns` — every namespace with status + age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ns"]}},{"id":"kubernetes.networkpolicies_list","title":"List NetworkPolicies across all namespaces","summary":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","description":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All network policies","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get networkpolicies -A"]}},{"id":"kubernetes.node_describe","title":"kubectl describe node","summary":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","description":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} describe node \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.nodes_list","title":"List cluster nodes","summary":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","description":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get nodes -o wide --show-labels"]}},{"id":"kubernetes.nodes_top","title":"Nodes by CPU + memory","summary":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","description":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Node utilization","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} top nodes"]}},{"id":"kubernetes.pod_describe","title":"kubectl describe pod","summary":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","description":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" describe pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_logs","title":"Tail pod logs","summary":"Tail the last N lines from one container in a pod.","description":"Tail the last N lines from one container in a pod.","kind":"exec","risk":"low","side_effects":["One kubectl logs invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default container).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last 200 lines","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_previous_logs","title":"Tail PREVIOUS container logs (crash debug)","summary":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","description":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","kind":"exec","risk":"low","side_effects":["One kubectl logs invocation with --previous.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last logs from a crashed container","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --previous --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pods_list","title":"List pods across all namespaces","summary":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","description":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context to use. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A -o wide"]}},{"id":"kubernetes.pods_problem","title":"Pods NOT in Running/Succeeded","summary":"Filter pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","description":"Filter pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Show problem pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded -o wide"]}},{"id":"kubernetes.pods_top","title":"Pods by CPU (metrics-server)","summary":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","description":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Top CPU consumers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","pods=$(kubectl ${KCTX:+--context=$KCTX} top pod -A --sort-by=cpu); status=$?\nprintf '%s\\n' \"$pods\" | head -50\nexit $status\n"]}},{"id":"kubernetes.pv_list","title":"List PersistentVolumes","summary":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","description":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All persistent volumes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pv"]}},{"id":"kubernetes.pvcs_list","title":"List PVCs across all namespaces","summary":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","description":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All PVCs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pvc -A"]}},{"id":"kubernetes.quotas_list","title":"ResourceQuota + LimitRange for a namespace","summary":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","description":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace to inspect.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Quotas in a namespace","args":{"namespace":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n $NS get resourcequota,limitrange"]}},{"id":"kubernetes.rollout_history","title":"kubectl rollout history","summary":"Return the revision history for a deployment / statefulset / daemonset.","description":"Return the revision history for a deployment / statefulset / daemonset.","kind":"exec","risk":"low","side_effects":["One kubectl rollout history invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"History for one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout history {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_restart","title":"kubectl rollout restart (rolling)","summary":"Trigger a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","description":"Trigger a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout of the resource.","Pods are replaced one-by-one; in-flight requests are drained per pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rolling restart of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout restart {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_status","title":"kubectl rollout status","summary":"Report the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","description":"Report the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","kind":"exec","risk":"low","side_effects":["One kubectl rollout status invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Status of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout status {{ args.kind }}/\"$2\" --watch=false","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_undo","title":"kubectl rollout undo (rollback)","summary":"Roll back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","description":"Roll back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout to the previous revision.","Pods replaced one-by-one; previous container image becomes current."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rollback the api deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout undo {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.scale_deployment","title":"Scale a deployment","summary":"Set deployment replica count; 0 stops every pod and takes the workload offline. Use to scale up before a traffic event or scale down to drain.","description":"Set deployment replica count; 0 stops every pod and takes the workload offline. Use to scale up before a traffic event or scale down to drain.","kind":"exec","risk":"high","side_effects":["Triggers scale up/down.","Pods created or terminated to reach the target replica count."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"replicas","type":"integer","required":true,"description":"Target replica count.","validation":{"min":0,"max":1000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Scale api to 10 replicas","args":{"name":"api","namespace":"default","replicas":10}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" scale deploy/\"$2\" --replicas={{ args.replicas }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.services_list","title":"List services across all namespaces","summary":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","description":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get svc -A"]}},{"id":"kubernetes.set_image","title":"Set deployment container image","summary":"Update one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","description":"Update one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","kind":"exec","risk":"high","side_effects":["Updates the deployment spec.","Triggers a rolling update; pods replaced one-by-one."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":true,"description":"Container name (from the pod spec).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"image","type":"string","required":true,"description":"Image ref (repository:tag).","validation":{"pattern":"^[a-zA-Z0-9_./@:\\-]{1,256}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Update api to a new image","args":{"container":"api","image":"ghcr.io/example/api:v1.42.0","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" set image deploy/\"$2\" \"$3\"=\"$4\"","emisar","{{ args.namespace }}","{{ args.name }}","{{ args.container }}","{{ args.image }}"]}},{"id":"kubernetes.statefulsets_list","title":"List statefulsets","summary":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","description":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All statefulsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get sts -A"]}},{"id":"kubernetes.storageclasses_list","title":"List StorageClasses","summary":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","description":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All storage classes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get storageclass"]}},{"id":"kubernetes.uncordon","title":"kubectl uncordon node","summary":"Mark a node schedulable again. Reverse of cordon.","description":"Mark a node schedulable again. Reverse of cordon.","kind":"exec","risk":"medium","side_effects":["Node marked schedulable.","New pods may schedule onto it."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Uncordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} uncordon \"$1\"","emisar","{{ args.name }}"]}}]},{"version":"0.2.3","content_hash":"sha256:8622e94be0fc89f9c2ecb7ebe3ff2dbeaada33cdb6c3c8caa71c269bb7bde99d","tarball_url":"https://registry.emisar.dev/v1/packs/kubernetes/0.2.3/8622e94be0fc89f9c2ecb7ebe3ff2dbeaada33cdb6c3c8caa71c269bb7bde99d/pack.tar.gz","actions":[{"id":"kubernetes.api_versions","title":"kubectl api-versions","summary":"Lists API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","description":"Lists API versions available on the cluster — useful for \"does this k8s version support …?\" checks.","kind":"exec","risk":"low","side_effects":["One kubectl api-versions invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"API versions","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} api-versions"]}},{"id":"kubernetes.auth_can_i","title":"List my RBAC permissions (auth can-i --list)","summary":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","description":"`kubectl auth can-i --list` — every action the kubeconfig identity is allowed, optionally scoped to one namespace. Confirms whether the runner's identity can perform the pack's mutators (drain, scale, delete). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl auth can-i invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Namespace to scope to. Empty = current/default.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All my permissions","args":{}},{"title":"In one namespace","args":{"namespace":"kube-system"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} ${NS:+-n $NS} auth can-i --list"]}},{"id":"kubernetes.cluster_info","title":"kubectl cluster-info","summary":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","description":"Show API server, DNS, and CoreDNS endpoints for the configured cluster.","kind":"exec","risk":"low","side_effects":["One kubectl cluster-info invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cluster info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cluster-info"]}},{"id":"kubernetes.control_plane_health","title":"Control-plane readiness (/readyz?verbose)","summary":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","description":"`kubectl get --raw '/readyz?verbose'` — the API server's per-check readiness (etcd, scheduling, informers, …). The modern replacement for the deprecated componentstatuses API. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get --raw invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Control-plane readiness","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get --raw '/readyz?verbose'"]}},{"id":"kubernetes.cordon","title":"kubectl cordon node","summary":"Marks a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","description":"Marks a node unschedulable. Existing pods stay; new pods won't be scheduled there. First step before draining.","kind":"exec","risk":"high","side_effects":["Node marked unschedulable.","Existing pods unaffected; new pods routed elsewhere."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Cordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} cordon \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.crds_list","title":"List CustomResourceDefinitions","summary":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","description":"`kubectl get crd` — installed CustomResourceDefinitions (an inventory of the operators/controllers extending the cluster). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All CRDs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get crd"]}},{"id":"kubernetes.cronjobs_list","title":"List CronJobs across all namespaces","summary":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","description":"`kubectl get cronjobs -A` — schedule, suspend state, last-schedule time, and active count. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All cronjobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get cronjobs -A"]}},{"id":"kubernetes.daemonsets_list","title":"List daemonsets","summary":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","description":"`kubectl get ds -A` — daemonset name, desired/current/ready counts, node selector.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All daemonsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ds -A"]}},{"id":"kubernetes.delete_pod","title":"Delete one pod (force-restart-by-killing)","summary":"Deletes one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","description":"Deletes one pod by name. Use to force-restart a single pod (the controller will recreate it). Faster than rollout_restart for a one-off bad pod. Namespace required to prevent wildcard mistakes.","kind":"exec","risk":"high","side_effects":["Pod sent SIGTERM, then SIGKILL after terminationGracePeriodSeconds.","Controller recreates the pod unless it was a standalone Pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name (no wildcards).","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Delete a stuck pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" delete pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.deployments_list","title":"List deployments","summary":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","description":"`kubectl get deploy -A` — replica counts (desired/current/available), age, image references.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All deployments","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get deploy -A"]}},{"id":"kubernetes.drain","title":"kubectl drain node (cordon + evict)","summary":"Cordons the node and evicts every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","description":"Cordons the node and evicts every pod that has a controller (Deployment/StatefulSet/etc). DaemonSets are ignored and emptyDir data is deleted with --delete-emptydir-data. Use before scheduled maintenance.","kind":"exec","risk":"critical","side_effects":["Node marked unschedulable.","Every controller-managed pod evicted; recreated elsewhere.","emptyDir volumes on this node are lost."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Drain one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} drain \"$1\" --ignore-daemonsets --delete-emptydir-data","emisar","{{ args.name }}"]}},{"id":"kubernetes.endpoints_list","title":"List endpoints across all namespaces","summary":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","description":"`kubectl get endpoints -A` — the ready backend IPs behind each Service. An empty endpoint set means a Service has no ready pods (a common \"service is down but the Deployment looks fine\" cause). Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All endpoints","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get endpoints -A"]}},{"id":"kubernetes.events_for_pod","title":"Events for one pod","summary":"List field-selected events that reference one pod.","description":"List field-selected events that reference one pod.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Events for one pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get events --field-selector involvedObject.kind=Pod,involvedObject.name=\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.events_recent","title":"Recent cluster events","summary":"List the last 50 events across all namespaces, sorted by last timestamp.","description":"List the last 50 events across all namespaces, sorted by last timestamp.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Recent events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -50\nexit $status\n"]}},{"id":"kubernetes.events_warnings","title":"Recent Warning events (all namespaces)","summary":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","description":"List the most recent Warning-type events cluster-wide, oldest-to-newest (FailedScheduling, BackOff, FailedMount, Unhealthy, …). The fastest cluster-wide \"what is wrong right now\". Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get events invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Warning events","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","events=$(kubectl ${KCTX:+--context=$KCTX} get events -A --field-selector type=Warning --sort-by=.lastTimestamp); status=$?\nprintf '%s\\n' \"$events\" | tail -n 60\nexit $status\n"]}},{"id":"kubernetes.get_yaml","title":"Get resource YAML","summary":"Returns the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","description":"Returns the full YAML definition of one resource. Kind is restricted to a safe enum that excludes secrets and configmaps (their .data carries credentials) and arbitrary CRDs of unknown size — read those via a dedicated higher-risk action, not this auto-allowed one.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":true,"description":"Resource kind.","validation":{"enum":["pod","deployment","statefulset","daemonset","service","ingress","pvc","hpa","cronjob","job"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"YAML of one deployment","args":{"kind":"deployment","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" get {{ args.kind }}/\"$2\" -o yaml","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.hpa_list","title":"List HorizontalPodAutoscalers","summary":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","description":"`kubectl get hpa -A` — targets (current/desired utilization), min/max replicas, and current replicas. Why a deployment is (or isn't) scaling. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All HPAs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get hpa -A"]}},{"id":"kubernetes.ingresses_list","title":"List ingresses across all namespaces","summary":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","description":"`kubectl get ingress -A` — ingress name, hosts, addresses, TLS hosts.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All ingresses","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ingress -A"]}},{"id":"kubernetes.jobs_list","title":"List Jobs across all namespaces","summary":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","description":"`kubectl get jobs -A` — completions, duration, age. Spot failed or stuck batch jobs. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All jobs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get jobs -A"]}},{"id":"kubernetes.namespaces","title":"List namespaces","summary":"`kubectl get ns` — every namespace with status + age.","description":"`kubectl get ns` — every namespace with status + age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get ns"]}},{"id":"kubernetes.networkpolicies_list","title":"List NetworkPolicies across all namespaces","summary":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","description":"`kubectl get networkpolicies -A` — which namespaces have NetworkPolicies and their pod selectors. Use when traffic is being unexpectedly allowed or blocked. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All network policies","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get networkpolicies -A"]}},{"id":"kubernetes.node_describe","title":"kubectl describe node","summary":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","description":"Show the full describe output for one node — capacity, allocatable, conditions, addresses, taints, pods, events.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} describe node \"$1\"","emisar","{{ args.name }}"]}},{"id":"kubernetes.nodes_list","title":"List cluster nodes","summary":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","description":"`kubectl get nodes -o wide --show-labels` — node names, status, roles, age, k8s version, OS, kernel, container runtime. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get nodes -o wide --show-labels"]}},{"id":"kubernetes.nodes_top","title":"Nodes by CPU + memory","summary":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","description":"`kubectl top nodes` — per-node CPU and memory utilization. Requires metrics-server.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Node utilization","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} top nodes"]}},{"id":"kubernetes.pod_describe","title":"kubectl describe pod","summary":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","description":"Show the full describe output — events, container states, conditions, volume mounts, scheduled node. The canonical \"why isn't this pod running?\" answer.","kind":"exec","risk":"low","side_effects":["One kubectl describe invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Describe a pod","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" describe pod \"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_logs","title":"Tail pod logs","summary":"Tail the last N lines from one container in a pod.","description":"Tail the last N lines from one container in a pod.","kind":"exec","risk":"low","side_effects":["One kubectl logs invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default container).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last 200 lines","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pod_previous_logs","title":"Tail PREVIOUS container logs (crash debug)","summary":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","description":"`kubectl logs --previous` — logs from the previously crashed container instance. The go-to action for CrashLoopBackOff: the current container has nothing yet, the crashed one explains why.","kind":"exec","risk":"low","side_effects":["One kubectl logs invocation with --previous.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Pod name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":false,"default":"","description":"Container name (empty = default).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$|^$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":10000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Last logs from a crashed container","args":{"name":"api-7d4f8c5b8c-x2nzp","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" logs \"$2\" ${CONT:+-c $CONT} --previous --tail={{ args.lines }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.pods_list","title":"List pods across all namespaces","summary":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","description":"`kubectl get pods -A -o wide` — every pod with its node, IP, status, and age. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context to use. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A -o wide"]}},{"id":"kubernetes.pods_problem","title":"Pods NOT in Running/Succeeded","summary":"Filters pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","description":"Filters pods to only those NOT in Running or Succeeded phase — Pending, Failed, CrashLoopBackOff, ImagePullBackOff, etc. The fastest \"what's broken right now?\" query. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Show problem pods","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded -o wide"]}},{"id":"kubernetes.pods_top","title":"Pods by CPU (metrics-server)","summary":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","description":"`kubectl top pod -A --sort-by=cpu | head -50` — top 50 pods by CPU. Requires metrics-server to be installed. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl top invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Top CPU consumers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","pods=$(kubectl ${KCTX:+--context=$KCTX} top pod -A --sort-by=cpu); status=$?\nprintf '%s\\n' \"$pods\" | head -50\nexit $status\n"]}},{"id":"kubernetes.pv_list","title":"List PersistentVolumes","summary":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","description":"`kubectl get pv` — capacity, access modes, reclaim policy, status (Bound/Released/Available), bound claim, and storage class. Cluster-scoped; complements the namespaced pvcs_list. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All persistent volumes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pv"]}},{"id":"kubernetes.pvcs_list","title":"List PVCs across all namespaces","summary":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","description":"`kubectl get pvc -A` — persistent volume claims, bound state, size, storage class.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All PVCs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get pvc -A"]}},{"id":"kubernetes.quotas_list","title":"ResourceQuota + LimitRange for a namespace","summary":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","description":"`kubectl -n <ns> get resourcequota,limitrange` — the quota usage and default request/limit ranges for one namespace. Why a pod can't be created (\"exceeded quota\") or gets unexpected defaults. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace to inspect.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Quotas in a namespace","args":{"namespace":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n $NS get resourcequota,limitrange"]}},{"id":"kubernetes.rollout_history","title":"kubectl rollout history","summary":"Returns the revision history for a deployment / statefulset / daemonset.","description":"Returns the revision history for a deployment / statefulset / daemonset.","kind":"exec","risk":"low","side_effects":["One kubectl rollout history invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"History for one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout history {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_restart","title":"kubectl rollout restart (rolling)","summary":"Triggers a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","description":"Triggers a rolling restart — pods are replaced one-by-one respecting maxSurge/maxUnavailable. In-flight requests on terminated pods are gracefully drained per pod terminationGracePeriodSeconds.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout of the resource.","Pods are replaced one-by-one; in-flight requests are drained per pod."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rolling restart of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout restart {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_status","title":"kubectl rollout status","summary":"Reports the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","description":"Reports the rollout progress of a deployment / statefulset / daemonset. Bounded with --watch=false so it returns immediately.","kind":"exec","risk":"low","side_effects":["One kubectl rollout status invocation.","Read-only."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Status of one deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout status {{ args.kind }}/\"$2\" --watch=false","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.rollout_undo","title":"kubectl rollout undo (rollback)","summary":"Rolls back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","description":"Rolls back to the previous revision. Bring `rollout_history` first to confirm what \"previous\" means in this case.","kind":"exec","risk":"high","side_effects":["Triggers a fresh rollout to the previous revision.","Pods replaced one-by-one; previous container image becomes current."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"kind","type":"string","required":false,"default":"deployment","description":"Resource kind.","validation":{"enum":["deployment","statefulset","daemonset"]}},{"name":"name","type":"string","required":true,"description":"Resource name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Rollback the api deployment","args":{"name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" rollout undo {{ args.kind }}/\"$2\"","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.scale_deployment","title":"Scale a deployment","summary":"Sets deployment replica count. Use to scale up before a traffic event or scale down to drain.","description":"Sets deployment replica count. Use to scale up before a traffic event or scale down to drain.","kind":"exec","risk":"high","side_effects":["Triggers scale up/down.","Pods created or terminated to reach the target replica count."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"replicas","type":"integer","required":true,"description":"Target replica count.","validation":{"min":0,"max":1000}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Scale api to 10 replicas","args":{"name":"api","namespace":"default","replicas":10}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" scale deploy/\"$2\" --replicas={{ args.replicas }}","emisar","{{ args.namespace }}","{{ args.name }}"]}},{"id":"kubernetes.services_list","title":"List services across all namespaces","summary":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","description":"`kubectl get svc -A` — service name, type, cluster IP, external IP, ports.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get svc -A"]}},{"id":"kubernetes.set_image","title":"Set deployment container image","summary":"Updates one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","description":"Updates one container's image in a deployment — triggers a rolling update. Container name and image ref are pattern-restricted.","kind":"exec","risk":"high","side_effects":["Updates the deployment spec.","Triggers a rolling update; pods replaced one-by-one."],"args":[{"name":"namespace","type":"string","required":true,"description":"Namespace.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"name","type":"string","required":true,"description":"Deployment name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"container","type":"string","required":true,"description":"Container name (from the pod spec).","validation":{"pattern":"^[a-z0-9][a-z0-9\\-]{0,62}$"}},{"name":"image","type":"string","required":true,"description":"Image ref (repository:tag).","validation":{"pattern":"^[a-zA-Z0-9_./@:\\-]{1,256}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Update api to a new image","args":{"container":"api","image":"ghcr.io/example/api:v1.42.0","name":"api","namespace":"default"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} -n \"$1\" set image deploy/\"$2\" \"$3\"=\"$4\"","emisar","{{ args.namespace }}","{{ args.name }}","{{ args.container }}","{{ args.image }}"]}},{"id":"kubernetes.statefulsets_list","title":"List statefulsets","summary":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","description":"`kubectl get sts -A` — statefulset name, ready/replicas, age.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All statefulsets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get sts -A"]}},{"id":"kubernetes.storageclasses_list","title":"List StorageClasses","summary":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","description":"`kubectl get storageclass` — provisioner, reclaim policy, volume binding mode, and which is the default class. Read-only.","kind":"exec","risk":"low","side_effects":["One kubectl get invocation.","Read-only."],"args":[{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context. Empty = current-context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"All storage classes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} get storageclass"]}},{"id":"kubernetes.uncordon","title":"kubectl uncordon node","summary":"Marks a node schedulable again. Reverse of cordon.","description":"Marks a node schedulable again. Reverse of cordon.","kind":"exec","risk":"medium","side_effects":["Node marked schedulable.","New pods may schedule onto it."],"args":[{"name":"name","type":"string","required":true,"description":"Node name.","validation":{"pattern":"^[a-z0-9][a-z0-9.\\-]{0,253}$"}},{"name":"context","type":"string","required":false,"default":"","description":"kubeconfig context.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{0,128}$"}}],"examples":[{"title":"Uncordon one node","args":{"name":"ip-10-0-1-23.eu-west-1.compute.internal"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","kubectl ${KCTX:+--context=$KCTX} uncordon \"$1\"","emisar","{{ args.name }}"]}}]}]},{"id":"linux-core","name":"Linux core operations pack","version":"0.4.6","description":"Read-only Linux diagnostics plus narrow service control. Disk, mem, uptime, journalctl, log grep + tail, users/auth introspection, cron audit, network state, kernel info, and systemctl control. The front-line pack every Linux host gets.","vendor":"emisar","homepage":"https://emisar.dev/packs/linux-core","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/linux-core","content_hash":"sha256:d57c3acc6ea7740cfc966de359ce90f0152295d7e4d1a29f41673c571d210ebc","tarball_url":"https://registry.emisar.dev/v1/packs/linux-core/0.4.6/d57c3acc6ea7740cfc966de359ce90f0152295d7e4d1a29f41673c571d210ebc/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","notes":["Most read-only diagnostics need no privilege. Journal, protected-log, storage, policy, service-control, and reboot actions are mapped below.","linux.last_logins requires the `last` command. On Debian 13 install `wtmpdb`; install `libpam-wtmpdb` as well so PAM records login history in wtmpdb."],"host_access":[{"actions":["linux.disk_smart","linux.lvm_status","linux.mdadm_status","linux.hardware_summary","linux.sudoers_dump","linux.crontab_all","linux.systemctl_start","linux.systemctl_stop","linux.systemctl_restart","linux.systemctl_reload","linux.systemctl_enable","linux.systemctl_disable","linux.reboot_host"],"requirement":"Read protected storage and policy state, control arbitrary services, or reboot the host.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-linux-core-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. The listed actions can read sensitive host policy, control any systemd unit, and reboot the machine."}]},{"actions":["linux.journalctl","linux.journalctl_grep","linux.grep_log","linux.tail_log","linux.failed_logins","linux.cron_recent"],"requirement":"Read systemd journal entries and protected logs on Debian or Ubuntu.","recipes":[{"name":"Add the Emisar service user to system log-reader groups","commands":["sudo usermod -aG adm,systemd-journal emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx adm","id -nG emisar | tr ' ' '\\n' | grep -Fx systemd-journal","sudo -u emisar journalctl --no-pager -n 1 >/dev/null"],"impact":"Every process running as emisar can read the system journal and every host log granted to adm, including logs unrelated to the selected actions."}]}],"verify":"linux.uptime"},"actions":[{"id":"linux.arp_neighbors","title":"ARP / IPv6 neighbor table","summary":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","description":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["neigh","show"]}},{"id":"linux.cpu_info","title":"CPU topology and features","summary":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","description":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","kind":"exec","risk":"low","side_effects":["One lscpu invocation.","Read-only."],"args":[],"examples":[{"title":"CPU layout + features","args":{}}],"search_terms":[],"command":{"binary":"lscpu","argv":[]}},{"id":"linux.cron_recent","title":"Recent cron job execution log","summary":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One journalctl invocation.","Read-only, but exposes cron command lines (may include inline secrets)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent CRON entries to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 cron entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -u cron -u crond -t CRON -t CROND --no-pager -n {{ args.count }}"]}},{"id":"linux.crontab_all","title":"All user crontabs + system cron dirs","summary":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Iterates user crontabs + reads /etc/cron.*.","Read-only, but requires root and exposes cron command lines (may include inline secrets)."],"args":[],"examples":[{"title":"Every scheduled job on this host","args":{}}],"search_terms":["scheduled jobs","scheduled tasks"],"command":{"binary":"/bin/sh","argv":["-c","for u in $(getent passwd | awk -F: '$7 !~ /nologin|false/ {print $1}'); do echo \"--- crontab -u $u ---\"; crontab -l -u \"$u\" 2>/dev/null; done; echo '--- /etc/crontab ---'; cat /etc/crontab 2>/dev/null; echo '--- /etc/cron.d/ ---'; ls -la /etc/cron.d/ 2>/dev/null; for d in hourly daily weekly monthly; do echo \"--- /etc/cron.$d/ ---\"; ls -la \"/etc/cron.$d/\" 2>/dev/null; done"]}},{"id":"linux.disk_smart","title":"SMART health for one disk","summary":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","description":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","kind":"exec","risk":"low","side_effects":["One smartctl invocation.","Reads SMART registers; no writes to the disk."],"args":[{"name":"device","type":"string","required":true,"description":"Block device under /dev (e.g. sda, nvme0n1).","validation":{"pattern":"^[a-zA-Z0-9]{1,16}$"}},{"name":"device_type","type":"string","required":false,"default":"auto","description":"smartctl device type (-d). \"auto\" (default) auto-detects direct ATA/SATA/NVMe disks; use \"megaraid,N\" or \"cciss,N\" for a disk behind a RAID controller, or \"sat\"/\"scsi\"/\"nvme\" to force a transport.","validation":{"pattern":"^(auto|ata|sat|scsi|nvme|megaraid,[0-9]{1,3}|cciss,[0-9]{1,3}|aacraid,[0-9]{1,3},[0-9]{1,3},[0-9]{1,3})$","max_length":32}}],"examples":[{"title":"SMART for sda (direct)","args":{"device":"sda"}},{"title":"SMART for a disk behind a PERC / megaraid controller","args":{"device":"sda","device_type":"megaraid,0"}}],"search_terms":["failing drive","bad sectors"],"command":{"binary":"smartctl","argv":["-d","{{ args.device_type }}","-H","-A","/dev/{{ args.device }}"]}},{"id":"linux.disk_usage","title":"Filesystem disk usage","summary":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","description":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","kind":"exec","risk":"low","side_effects":["Reads filesystem metadata via df.","Touches no files.","Does not mount, unmount, or modify anything."],"args":[{"name":"paths","type":"string_array","required":false,"default":["/"],"description":"One or more paths to inspect. Each path is passed to df -P -h.","validation":{"allowed_prefixes":["/","/var","/tmp","/home","/usr","/opt"],"max_items":8}}],"examples":[{"title":"Check root filesystem usage","args":{}},{"title":"Check /var and /tmp","args":{"paths":["/var","/tmp"]}}],"search_terms":["no space left on device","out of space"],"command":{"binary":"df","argv":["-P","-h","{{ args.paths }}"]}},{"id":"linux.failed_logins","title":"Recent failed login attempts","summary":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","description":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","kind":"exec","risk":"medium","side_effects":["One journalctl read of the auth/authpriv journal (root or the systemd-journal group).","Output includes source IPs and usernames (PII).","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many of the most recent failed attempts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 failed login attempts","args":{}}],"search_terms":["under attack","intrusion","brute force","break-in","hacked"],"command":{"binary":"journalctl","argv":["--facility=auth,authpriv","--grep","Failed password|Invalid user|Failed publickey|authentication failure|FAILED","--no-pager","-n","{{ args.count }}"]}},{"id":"linux.grep_log","title":"Grep a log file","summary":"Grep an extended regex (POSIX -E) against a log file under /var/log.","description":"Grep an extended regex (POSIX -E) against a log file under /var/log. Read-only. Returns matching lines with line numbers (-n) up to max_lines. Use to find recent occurrences of a specific identifier (request ID, user ID, IP) or to spot error patterns without dumping the whole file. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"medium","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"pattern","type":"string","required":true,"description":"Extended regex (POSIX ERE) pattern. Passed to grep -E.","validation":{"pattern":"^.{1,512}$"}},{"name":"max_lines","type":"integer","required":false,"default":200,"description":"Cap on returned matching lines (grep -m).","validation":{"min":1,"max":2000}}],"examples":[{"title":"Recent 5xx in nginx access log","args":{"file":"/var/log/nginx/access.log","max_lines":100,"pattern":" 5[0-9][0-9] "}},{"title":"Find a request id","args":{"file":"/var/log/app/server.log","pattern":"req_abc123"}}],"search_terms":[],"command":{"binary":"grep","argv":["-E","-n","-m","{{ args.max_lines }}","-e","{{ args.pattern }}","--","{{ args.file }}"]}},{"id":"linux.hardware_summary","title":"Hardware + BIOS summary via dmidecode","summary":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","description":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","kind":"exec","risk":"low","side_effects":["One dmidecode invocation.","Read-only."],"args":[],"examples":[{"title":"System + BIOS + chassis","args":{}}],"search_terms":[],"command":{"binary":"dmidecode","argv":["-t","system","-t","bios","-t","chassis"]}},{"id":"linux.inode_usage","title":"Inode usage per filesystem","summary":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","description":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Inode usage snapshot","args":{}}],"search_terms":["out of inodes"],"command":{"binary":"df","argv":["-i","-h"]}},{"id":"linux.journalctl","title":"Recent systemd journal entries","summary":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","description":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before leaving the host.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Recent Cassandra warnings","args":{"priority":"warning","since":"1h","unit":"cassandra"}}],"search_terms":["app crash","keeps crashing","crash loop"],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--no-pager"]}},{"id":"linux.journalctl_grep","title":"Grep recent systemd journal entries","summary":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","description":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before egress.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$","max_length":128}},{"name":"grep","type":"string","required":true,"description":"Regex pattern passed to journalctl --grep.","validation":{"pattern":"^.{1,512}$"}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Cassandra journal entries mentioning compaction","args":{"grep":"compact","since":"6h","unit":"cassandra"}},{"title":"Nginx 5xx in journal","args":{"grep":" (5[0-9][0-9]) ","priority":"notice","unit":"nginx"}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--grep","{{ args.grep }}","--no-pager"]}},{"id":"linux.kernel_modules","title":"Loaded kernel modules sorted by size","summary":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","description":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","kind":"exec","risk":"low","side_effects":["One lsmod invocation.","Read-only."],"args":[],"examples":[{"title":"Largest loaded modules","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lsmod | sort -k 3 -n -r | head -30"]}},{"id":"linux.last_logins","title":"Recent successful logins","summary":"Show the last N successful logins via `last`. Depending on the distribution, `last` reads the legacy wtmp file or the wtmpdb login-history database. Shows user, terminal, source IP, and duration. Read-only.","description":"Show the last N successful logins via `last`. Depending on the distribution, `last` reads the legacy wtmp file or the wtmpdb login-history database. Shows user, terminal, source IP, and duration. Read-only.","kind":"exec","risk":"medium","side_effects":["One last invocation.","Reads the host's login-history database (legacy wtmp or wtmpdb)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent logins to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 successful logins","args":{}}],"search_terms":[],"command":{"binary":"last","argv":["-F","-n","{{ args.count }}"]}},{"id":"linux.lvm_status","title":"LVM volume / group / PV summary","summary":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","description":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","kind":"exec","risk":"low","side_effects":["Three LVM CLI invocations.","Read-only."],"args":[],"examples":[{"title":"LVM snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lvs; echo; vgs; echo; pvs"]}},{"id":"linux.mdadm_status","title":"mdadm RAID array status","summary":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","description":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","kind":"exec","risk":"low","side_effects":["One cat + one mdadm --detail per array.","Read-only."],"args":[],"examples":[{"title":"Array health snapshot","args":{}}],"search_terms":["raid rebuild","raid degraded","failed drive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/mdstat; for md in /dev/md[0-9]*; do [ -e \"$md\" ] || continue; echo; mdadm --detail \"$md\"; done"]}},{"id":"linux.memory","title":"System memory snapshot","summary":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","description":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","kind":"exec","risk":"low","side_effects":["Reads /proc/meminfo via the free utility.","Touches no files."],"args":[],"examples":[{"title":"Snapshot memory","args":{}}],"search_terms":[],"command":{"binary":"free","argv":["-m"]}},{"id":"linux.memory_detailed","title":"Full /proc/meminfo","summary":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","description":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","kind":"exec","risk":"low","side_effects":["One read of /proc/meminfo.","Read-only."],"args":[],"examples":[{"title":"Full memory accounting","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/meminfo"]}},{"id":"linux.mount_status","title":"Mounted filesystems","summary":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","description":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","kind":"exec","risk":"low","side_effects":["One findmnt invocation.","Read-only."],"args":[],"examples":[{"title":"All mounted filesystems","args":{}}],"search_terms":["read only filesystem"],"command":{"binary":"/bin/sh","argv":["-c","findmnt -A"]}},{"id":"linux.network_interfaces","title":"Network interfaces","summary":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","description":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"All interfaces (JSON)","args":{}}],"search_terms":["link down","ifconfig"],"command":{"binary":"ip","argv":["-j","addr","show"]}},{"id":"linux.network_routes","title":"Routing table + policy rules","summary":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","description":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","kind":"exec","risk":"low","side_effects":["Three ip invocations.","Read-only."],"args":[],"examples":[{"title":"All routes","args":{}}],"search_terms":["default gateway","no route to host"],"command":{"binary":"/bin/sh","argv":["-c","ip route show; echo; ip rule show; echo; ip -6 route show"]}},{"id":"linux.os_release","title":"Distro + kernel identity","summary":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","description":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","kind":"exec","risk":"low","side_effects":["Two file/utility reads.","Read-only."],"args":[],"examples":[{"title":"Distro + kernel","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/os-release; echo; uname -a"]}},{"id":"linux.reboot_host","title":"Schedule a host reboot","summary":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","description":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","kind":"exec","risk":"critical","side_effects":["Wall message broadcast to all logged-in users.","One-minute timer set; kernel shutdown begins after.","Every running service stops; all open connections drop."],"args":[{"name":"note","type":"string","required":true,"description":"Message broadcast to logged-in users in the reboot warning.","validation":{"pattern":"^[a-zA-Z0-9 .,_:;/\\-]{4,200}$"}}],"examples":[{"title":"Reboot for kernel upgrade","args":{"note":"kernel upgrade to 5.15.140 - pending /var/run/reboot-required"}}],"search_terms":["restart host","reboot box","restart server"],"command":{"binary":"shutdown","argv":["-r","+1","emisar-initiated reboot: {{ args.note }}"]}},{"id":"linux.sudoers_dump","title":"sudoers configuration audit","summary":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","description":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /etc/sudoers and ls of /etc/sudoers.d/.","Requires root or sudo-readable perms."],"args":[],"examples":[{"title":"Sudoers audit","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -r /etc/sudoers ] || { echo '/etc/sudoers is not readable by this runner identity' >&2; exit 1; }; cat /etc/sudoers; echo; ls -la /etc/sudoers.d/"]}},{"id":"linux.systemctl_disable","title":"Disable a systemd unit at boot","summary":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","description":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Removes symlinks under /etc/systemd/system/.","Idempotent."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Disable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["disable","{{ args.unit }}"]}},{"id":"linux.systemctl_enable","title":"Enable a systemd unit at boot","summary":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","description":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Creates symlinks under /etc/systemd/system/.","Idempotent — re-running on an already-enabled unit is a no-op."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Enable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["enable","{{ args.unit }}"]}},{"id":"linux.systemctl_reload","title":"Reload a systemd unit's config","summary":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","description":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","kind":"exec","risk":"high","side_effects":["Sends SIGHUP (or the configured reload signal) to the unit.","Unit re-reads its config; existing workers continue."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Reload nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"linux.systemctl_restart","title":"Restart a systemd unit","summary":"Restart a named systemd unit.","description":"Restart a named systemd unit. Clients will see an outage of seconds-to-minutes depending on the unit. Treat as a last-resort action: prefer diagnosis (logs, status, disk, memory) first. Never restart a database under load without confirming there is no in-flight repair, compaction, or similar background operation. WHICH units this runner may restart is an operator policy decision (high-risk → require_approval by default), not a fixed list; the unit is bounded to a valid systemd unit name so it can't carry shell metacharacters.","kind":"exec","risk":"high","side_effects":["Stops the named unit, then starts it.","Disconnects existing clients of the unit.","May trigger downstream alerts if the unit takes time to recover.","Does not modify configuration or on-disk state."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to restart (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Restart nginx after a config reload check","args":{"unit":"nginx"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"linux.systemctl_start","title":"Start a systemd unit","summary":"`systemctl start <unit>`. Brings a unit up and waits for the start job to finish, so a successful run means the unit reached its started state — a failed start fails the run rather than reporting a queued job.","description":"`systemctl start <unit>`. Brings a unit up and waits for the start job to finish, so a successful run means the unit reached its started state — a failed start fails the run rather than reporting a queued job.","kind":"exec","risk":"high","side_effects":["Starts the unit (and any required dependencies).","Triggers ExecStartPre/Post hooks declared in the unit."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Start nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","{{ args.unit }}"]}},{"id":"linux.systemctl_status","title":"Systemd unit status","summary":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","description":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","kind":"exec","risk":"low","side_effects":["Reads systemd state.","Touches no files."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to query.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Check Cassandra status","args":{"unit":"cassandra"}}],"search_terms":["service won't start","unit down","not running"],"command":{"binary":"systemctl","argv":["status","{{ args.unit }}","--no-pager"]}},{"id":"linux.systemctl_stop","title":"Stop a systemd unit","summary":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","description":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","kind":"exec","risk":"high","side_effects":["SIGTERMs (then SIGKILLs) the unit's processes.","Triggers ExecStop/ExecStopPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Stop nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","{{ args.unit }}"]}},{"id":"linux.tail_log","title":"Tail a log file","summary":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","description":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"medium","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines to return (tail -n).","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 lines of nginx error log","args":{"file":"/var/log/nginx/error.log","lines":100}},{"title":"Last 500 lines of an app log","args":{"file":"/var/log/app/server.log","lines":500}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","{{ args.file }}"]}},{"id":"linux.uptime","title":"System uptime and load average","summary":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","description":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","kind":"exec","risk":"low","side_effects":["Reads /proc/loadavg and /proc/uptime via the uptime utility.","Touches no files."],"args":[],"examples":[{"title":"Get uptime and load","args":{}}],"search_terms":["last reboot"],"command":{"binary":"uptime","argv":[]}},{"id":"linux.who_now","title":"Currently logged-in users","summary":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","description":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","kind":"exec","risk":"low","side_effects":["Two utility invocations.","Read-only."],"args":[],"examples":[{"title":"Current logins","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","who; echo; w"]}}],"previous_versions":[{"version":"0.4.3","content_hash":"sha256:42435a40d2dda7d22bd2648ef5987c08bd6eeb4391835b052818578de18e0cba","tarball_url":"https://registry.emisar.dev/v1/packs/linux-core/0.4.3/42435a40d2dda7d22bd2648ef5987c08bd6eeb4391835b052818578de18e0cba/pack.tar.gz","actions":[{"id":"linux.arp_neighbors","title":"ARP / IPv6 neighbor table","summary":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","description":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["neigh","show"]}},{"id":"linux.cpu_info","title":"CPU topology and features","summary":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","description":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","kind":"exec","risk":"low","side_effects":["One lscpu invocation.","Read-only."],"args":[],"examples":[{"title":"CPU layout + features","args":{}}],"search_terms":[],"command":{"binary":"lscpu","argv":[]}},{"id":"linux.cron_recent","title":"Recent cron job execution log","summary":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One journalctl invocation.","Read-only, but exposes cron command lines (may include inline secrets)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent CRON entries to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 cron entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -u cron -u crond -t CRON -t CROND --no-pager -n {{ args.count }}"]}},{"id":"linux.crontab_all","title":"All user crontabs + system cron dirs","summary":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Iterates user crontabs + reads /etc/cron.*.","Read-only, but requires root and exposes cron command lines (may include inline secrets)."],"args":[],"examples":[{"title":"Every scheduled job on this host","args":{}}],"search_terms":["scheduled jobs","scheduled tasks"],"command":{"binary":"/bin/sh","argv":["-c","for u in $(getent passwd | awk -F: '$7 !~ /nologin|false/ {print $1}'); do echo \"--- crontab -u $u ---\"; crontab -l -u \"$u\" 2>/dev/null; done; echo '--- /etc/crontab ---'; cat /etc/crontab 2>/dev/null; echo '--- /etc/cron.d/ ---'; ls -la /etc/cron.d/ 2>/dev/null; for d in hourly daily weekly monthly; do echo \"--- /etc/cron.$d/ ---\"; ls -la \"/etc/cron.$d/\" 2>/dev/null; done"]}},{"id":"linux.disk_smart","title":"SMART health for one disk","summary":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","description":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","kind":"exec","risk":"low","side_effects":["One smartctl invocation.","Reads SMART registers; no writes to the disk."],"args":[{"name":"device","type":"string","required":true,"description":"Block device under /dev (e.g. sda, nvme0n1).","validation":{"pattern":"^[a-zA-Z0-9]{1,16}$"}},{"name":"device_type","type":"string","required":false,"default":"auto","description":"smartctl device type (-d). \"auto\" (default) auto-detects direct ATA/SATA/NVMe disks; use \"megaraid,N\" or \"cciss,N\" for a disk behind a RAID controller, or \"sat\"/\"scsi\"/\"nvme\" to force a transport.","validation":{"pattern":"^(auto|ata|sat|scsi|nvme|megaraid,[0-9]{1,3}|cciss,[0-9]{1,3}|aacraid,[0-9]{1,3},[0-9]{1,3},[0-9]{1,3})$","max_length":32}}],"examples":[{"title":"SMART for sda (direct)","args":{"device":"sda"}},{"title":"SMART for a disk behind a PERC / megaraid controller","args":{"device":"sda","device_type":"megaraid,0"}}],"search_terms":["failing drive","bad sectors"],"command":{"binary":"smartctl","argv":["-d","{{ args.device_type }}","-H","-A","/dev/{{ args.device }}"]}},{"id":"linux.disk_usage","title":"Filesystem disk usage","summary":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","description":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","kind":"exec","risk":"low","side_effects":["Reads filesystem metadata via df.","Touches no files.","Does not mount, unmount, or modify anything."],"args":[{"name":"paths","type":"string_array","required":false,"default":["/"],"description":"One or more paths to inspect. Each path is passed to df -P -h.","validation":{"allowed_prefixes":["/","/var","/tmp","/home","/usr","/opt"],"max_items":8}}],"examples":[{"title":"Check root filesystem usage","args":{}},{"title":"Check /var and /tmp","args":{"paths":["/var","/tmp"]}}],"search_terms":["no space left on device","out of space"],"command":{"binary":"df","argv":["-P","-h","{{ args.paths }}"]}},{"id":"linux.failed_logins","title":"Recent failed login attempts","summary":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","description":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","kind":"exec","risk":"medium","side_effects":["One journalctl read of the auth/authpriv journal (root or the systemd-journal group).","Output includes source IPs and usernames (PII).","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many of the most recent failed attempts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 failed login attempts","args":{}}],"search_terms":["under attack","intrusion","brute force","break-in","hacked"],"command":{"binary":"journalctl","argv":["--facility=auth,authpriv","--grep","Failed password|Invalid user|Failed publickey|authentication failure|FAILED","--no-pager","-n","{{ args.count }}"]}},{"id":"linux.grep_log","title":"Grep a log file","summary":"Grep an extended regex (POSIX -E) against a log file under /var/log.","description":"Grep an extended regex (POSIX -E) against a log file under /var/log. Read-only. Returns matching lines with line numbers (-n) up to max_lines. Use to find recent occurrences of a specific identifier (request ID, user ID, IP) or to spot error patterns without dumping the whole file. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"low","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"pattern","type":"string","required":true,"description":"Extended regex (POSIX ERE) pattern. Passed to grep -E.","validation":{"pattern":"^.{1,512}$"}},{"name":"max_lines","type":"integer","required":false,"default":200,"description":"Cap on returned matching lines (grep -m).","validation":{"min":1,"max":2000}}],"examples":[{"title":"Recent 5xx in nginx access log","args":{"file":"/var/log/nginx/access.log","max_lines":100,"pattern":" 5[0-9][0-9] "}},{"title":"Find a request id","args":{"file":"/var/log/app/server.log","pattern":"req_abc123"}}],"search_terms":[],"command":{"binary":"grep","argv":["-E","-n","-m","{{ args.max_lines }}","-e","{{ args.pattern }}","--","{{ args.file }}"]}},{"id":"linux.hardware_summary","title":"Hardware + BIOS summary via dmidecode","summary":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","description":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","kind":"exec","risk":"low","side_effects":["One dmidecode invocation.","Read-only."],"args":[],"examples":[{"title":"System + BIOS + chassis","args":{}}],"search_terms":[],"command":{"binary":"dmidecode","argv":["-t","system","-t","bios","-t","chassis"]}},{"id":"linux.inode_usage","title":"Inode usage per filesystem","summary":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","description":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Inode usage snapshot","args":{}}],"search_terms":["out of inodes"],"command":{"binary":"df","argv":["-i","-h"]}},{"id":"linux.journalctl","title":"Recent systemd journal entries","summary":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","description":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before leaving the host.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:-]{1,128}$","max_length":128}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Recent Cassandra warnings","args":{"priority":"warning","since":"1h","unit":"cassandra"}}],"search_terms":["app crash","keeps crashing","crash loop"],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--no-pager"]}},{"id":"linux.journalctl_grep","title":"Grep recent systemd journal entries","summary":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","description":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before egress.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:-]{1,128}$","max_length":128}},{"name":"grep","type":"string","required":true,"description":"Regex pattern passed to journalctl --grep.","validation":{"pattern":"^.{1,512}$"}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Cassandra journal entries mentioning compaction","args":{"grep":"compact","since":"6h","unit":"cassandra"}},{"title":"Nginx 5xx in journal","args":{"grep":" (5[0-9][0-9]) ","priority":"notice","unit":"nginx"}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--grep","{{ args.grep }}","--no-pager"]}},{"id":"linux.kernel_modules","title":"Loaded kernel modules sorted by size","summary":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","description":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","kind":"exec","risk":"low","side_effects":["One lsmod invocation.","Read-only."],"args":[],"examples":[{"title":"Largest loaded modules","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lsmod | sort -k 3 -n -r | head -30"]}},{"id":"linux.last_logins","title":"Recent successful logins","summary":"Show the last N successful logins via `last`. Depending on the distribution, `last` reads the legacy wtmp file or the wtmpdb login-history database. Shows user, terminal, source IP, and duration. Read-only.","description":"Show the last N successful logins via `last`. Depending on the distribution, `last` reads the legacy wtmp file or the wtmpdb login-history database. Shows user, terminal, source IP, and duration. Read-only.","kind":"exec","risk":"low","side_effects":["One last invocation.","Reads the host's login-history database (legacy wtmp or wtmpdb)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent logins to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 successful logins","args":{}}],"search_terms":[],"command":{"binary":"last","argv":["-F","-n","{{ args.count }}"]}},{"id":"linux.lvm_status","title":"LVM volume / group / PV summary","summary":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","description":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","kind":"exec","risk":"low","side_effects":["Three LVM CLI invocations.","Read-only."],"args":[],"examples":[{"title":"LVM snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lvs; echo; vgs; echo; pvs"]}},{"id":"linux.mdadm_status","title":"mdadm RAID array status","summary":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","description":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","kind":"exec","risk":"low","side_effects":["One cat + one mdadm --detail per array.","Read-only."],"args":[],"examples":[{"title":"Array health snapshot","args":{}}],"search_terms":["raid rebuild","raid degraded","failed drive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/mdstat; for md in /dev/md[0-9]*; do [ -e \"$md\" ] || continue; echo; mdadm --detail \"$md\"; done"]}},{"id":"linux.memory","title":"System memory snapshot","summary":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","description":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","kind":"exec","risk":"low","side_effects":["Reads /proc/meminfo via the free utility.","Touches no files."],"args":[],"examples":[{"title":"Snapshot memory","args":{}}],"search_terms":[],"command":{"binary":"free","argv":["-m"]}},{"id":"linux.memory_detailed","title":"Full /proc/meminfo","summary":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","description":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","kind":"exec","risk":"low","side_effects":["One read of /proc/meminfo.","Read-only."],"args":[],"examples":[{"title":"Full memory accounting","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/meminfo"]}},{"id":"linux.mount_status","title":"Mounted filesystems","summary":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","description":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","kind":"exec","risk":"low","side_effects":["One findmnt invocation.","Read-only."],"args":[],"examples":[{"title":"All mounted filesystems","args":{}}],"search_terms":["read only filesystem"],"command":{"binary":"/bin/sh","argv":["-c","findmnt -A"]}},{"id":"linux.network_interfaces","title":"Network interfaces","summary":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","description":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"All interfaces (JSON)","args":{}}],"search_terms":["link down","ifconfig"],"command":{"binary":"ip","argv":["-j","addr","show"]}},{"id":"linux.network_routes","title":"Routing table + policy rules","summary":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","description":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","kind":"exec","risk":"low","side_effects":["Three ip invocations.","Read-only."],"args":[],"examples":[{"title":"All routes","args":{}}],"search_terms":["default gateway","no route to host"],"command":{"binary":"/bin/sh","argv":["-c","ip route show; echo; ip rule show; echo; ip -6 route show"]}},{"id":"linux.os_release","title":"Distro + kernel identity","summary":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","description":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","kind":"exec","risk":"low","side_effects":["Two file/utility reads.","Read-only."],"args":[],"examples":[{"title":"Distro + kernel","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/os-release; echo; uname -a"]}},{"id":"linux.reboot_host","title":"Schedule a host reboot","summary":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","description":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","kind":"exec","risk":"critical","side_effects":["Wall message broadcast to all logged-in users.","One-minute timer set; kernel shutdown begins after.","Every running service stops; all open connections drop."],"args":[{"name":"note","type":"string","required":true,"description":"Message broadcast to logged-in users in the reboot warning.","validation":{"pattern":"^[a-zA-Z0-9 .,_:;/\\-]{4,200}$"}}],"examples":[{"title":"Reboot for kernel upgrade","args":{"note":"kernel upgrade to 5.15.140 - pending /var/run/reboot-required"}}],"search_terms":["restart host","reboot box","restart server"],"command":{"binary":"shutdown","argv":["-r","+1","emisar-initiated reboot: {{ args.note }}"]}},{"id":"linux.sudoers_dump","title":"sudoers configuration audit","summary":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","description":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /etc/sudoers and ls of /etc/sudoers.d/.","Requires root or sudo-readable perms."],"args":[],"examples":[{"title":"Sudoers audit","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/sudoers 2>/dev/null; echo; ls -la /etc/sudoers.d/ 2>/dev/null"]}},{"id":"linux.systemctl_disable","title":"Disable a systemd unit at boot","summary":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","description":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Removes symlinks under /etc/systemd/system/.","Idempotent."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Disable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["disable","{{ args.unit }}"]}},{"id":"linux.systemctl_enable","title":"Enable a systemd unit at boot","summary":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","description":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Creates symlinks under /etc/systemd/system/.","Idempotent — re-running on an already-enabled unit is a no-op."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Enable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["enable","{{ args.unit }}"]}},{"id":"linux.systemctl_reload","title":"Reload a systemd unit's config","summary":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","description":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","kind":"exec","risk":"high","side_effects":["Sends SIGHUP (or the configured reload signal) to the unit.","Unit re-reads its config; existing workers continue."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Reload nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"linux.systemctl_restart","title":"Restart a systemd unit","summary":"Restart a named systemd unit.","description":"Restart a named systemd unit. Clients will see an outage of seconds-to-minutes depending on the unit. Treat as a last-resort action: prefer diagnosis (logs, status, disk, memory) first. Never restart a database under load without confirming there is no in-flight repair, compaction, or similar background operation. WHICH units this runner may restart is an operator policy decision (high-risk → require_approval by default), not a fixed list; the unit is bounded to a valid systemd unit name so it can't carry shell metacharacters.","kind":"exec","risk":"high","side_effects":["Stops the named unit, then starts it.","Disconnects existing clients of the unit.","May trigger downstream alerts if the unit takes time to recover.","Does not modify configuration or on-disk state."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to restart (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:][A-Za-z0-9@._:-]{0,127}$","max_length":128}}],"examples":[{"title":"Restart nginx after a config reload check","args":{"unit":"nginx"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"linux.systemctl_start","title":"Start a systemd unit","summary":"`systemctl start <unit>`. Brings a unit up. The unit name is pattern-restricted to safe systemd unit naming. Combine with `linux.systemctl_status` afterward to confirm the unit reached active state.","description":"`systemctl start <unit>`. Brings a unit up. The unit name is pattern-restricted to safe systemd unit naming. Combine with `linux.systemctl_status` afterward to confirm the unit reached active state.","kind":"exec","risk":"high","side_effects":["Starts the unit (and any required dependencies).","Triggers ExecStartPre/Post hooks declared in the unit."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Start nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","--no-block","{{ args.unit }}"]}},{"id":"linux.systemctl_status","title":"Systemd unit status","summary":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","description":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","kind":"exec","risk":"low","side_effects":["Reads systemd state.","Touches no files."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to query.","validation":{"pattern":"^[a-zA-Z0-9@._][a-zA-Z0-9@._-]{0,127}$"}}],"examples":[{"title":"Check Cassandra status","args":{"unit":"cassandra"}}],"search_terms":["service won't start","unit down","not running"],"command":{"binary":"systemctl","argv":["status","{{ args.unit }}","--no-pager"]}},{"id":"linux.systemctl_stop","title":"Stop a systemd unit","summary":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","description":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","kind":"exec","risk":"high","side_effects":["SIGTERMs (then SIGKILLs) the unit's processes.","Triggers ExecStop/ExecStopPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Stop nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","--no-block","{{ args.unit }}"]}},{"id":"linux.tail_log","title":"Tail a log file","summary":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","description":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"low","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines to return (tail -n).","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 lines of nginx error log","args":{"file":"/var/log/nginx/error.log","lines":100}},{"title":"Last 500 lines of an app log","args":{"file":"/var/log/app/server.log","lines":500}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","{{ args.file }}"]}},{"id":"linux.uptime","title":"System uptime and load average","summary":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","description":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","kind":"exec","risk":"low","side_effects":["Reads /proc/loadavg and /proc/uptime via the uptime utility.","Touches no files."],"args":[],"examples":[{"title":"Get uptime and load","args":{}}],"search_terms":["last reboot"],"command":{"binary":"uptime","argv":[]}},{"id":"linux.who_now","title":"Currently logged-in users","summary":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","description":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","kind":"exec","risk":"low","side_effects":["Two utility invocations.","Read-only."],"args":[],"examples":[{"title":"Current logins","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","who; echo; w"]}}]},{"version":"0.4.1","content_hash":"sha256:a5852885bec7b265c98bc897b6c45448d88c3cc92b098cd3d221b4c98e20edd4","tarball_url":"https://registry.emisar.dev/v1/packs/linux-core/0.4.1/a5852885bec7b265c98bc897b6c45448d88c3cc92b098cd3d221b4c98e20edd4/pack.tar.gz","actions":[{"id":"linux.arp_neighbors","title":"ARP / IPv6 neighbor table","summary":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","description":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["neigh","show"]}},{"id":"linux.cpu_info","title":"CPU topology and features","summary":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","description":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","kind":"exec","risk":"low","side_effects":["One lscpu invocation.","Read-only."],"args":[],"examples":[{"title":"CPU layout + features","args":{}}],"search_terms":[],"command":{"binary":"lscpu","argv":[]}},{"id":"linux.cron_recent","title":"Recent cron job execution log","summary":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One journalctl invocation.","Read-only, but exposes cron command lines (may include inline secrets)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent CRON entries to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 cron entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -u cron -u crond -t CRON -t CROND --no-pager -n {{ args.count }}"]}},{"id":"linux.crontab_all","title":"All user crontabs + system cron dirs","summary":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Iterates user crontabs + reads /etc/cron.*.","Read-only, but requires root and exposes cron command lines (may include inline secrets)."],"args":[],"examples":[{"title":"Every scheduled job on this host","args":{}}],"search_terms":["scheduled jobs","scheduled tasks"],"command":{"binary":"/bin/sh","argv":["-c","for u in $(getent passwd | awk -F: '$7 !~ /nologin|false/ {print $1}'); do echo \"--- crontab -u $u ---\"; crontab -l -u \"$u\" 2>/dev/null; done; echo '--- /etc/crontab ---'; cat /etc/crontab 2>/dev/null; echo '--- /etc/cron.d/ ---'; ls -la /etc/cron.d/ 2>/dev/null; for d in hourly daily weekly monthly; do echo \"--- /etc/cron.$d/ ---\"; ls -la \"/etc/cron.$d/\" 2>/dev/null; done"]}},{"id":"linux.disk_smart","title":"SMART health for one disk","summary":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","description":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","kind":"exec","risk":"low","side_effects":["One smartctl invocation.","Reads SMART registers; no writes to the disk."],"args":[{"name":"device","type":"string","required":true,"description":"Block device under /dev (e.g. sda, nvme0n1).","validation":{"pattern":"^[a-zA-Z0-9]{1,16}$"}},{"name":"device_type","type":"string","required":false,"default":"auto","description":"smartctl device type (-d). \"auto\" (default) auto-detects direct ATA/SATA/NVMe disks; use \"megaraid,N\" or \"cciss,N\" for a disk behind a RAID controller, or \"sat\"/\"scsi\"/\"nvme\" to force a transport.","validation":{"pattern":"^(auto|ata|sat|scsi|nvme|megaraid,[0-9]{1,3}|cciss,[0-9]{1,3}|aacraid,[0-9]{1,3},[0-9]{1,3},[0-9]{1,3})$","max_length":32}}],"examples":[{"title":"SMART for sda (direct)","args":{"device":"sda"}},{"title":"SMART for a disk behind a PERC / megaraid controller","args":{"device":"sda","device_type":"megaraid,0"}}],"search_terms":["failing drive","bad sectors"],"command":{"binary":"smartctl","argv":["-d","{{ args.device_type }}","-H","-A","/dev/{{ args.device }}"]}},{"id":"linux.disk_usage","title":"Filesystem disk usage","summary":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","description":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","kind":"exec","risk":"low","side_effects":["Reads filesystem metadata via df.","Touches no files.","Does not mount, unmount, or modify anything."],"args":[{"name":"paths","type":"string_array","required":false,"default":["/"],"description":"One or more paths to inspect. Each path is passed to df -P -h.","validation":{"allowed_prefixes":["/","/var","/tmp","/home","/usr","/opt"],"max_items":8}}],"examples":[{"title":"Check root filesystem usage","args":{}},{"title":"Check /var and /tmp","args":{"paths":["/var","/tmp"]}}],"search_terms":["no space left on device","out of space"],"command":{"binary":"df","argv":["-P","-h","{{ args.paths }}"]}},{"id":"linux.failed_logins","title":"Recent failed login attempts","summary":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","description":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","kind":"exec","risk":"medium","side_effects":["One journalctl read of the auth/authpriv journal (root or the systemd-journal group).","Output includes source IPs and usernames (PII).","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many of the most recent failed attempts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 failed login attempts","args":{}}],"search_terms":["under attack","intrusion","brute force","break-in","hacked"],"command":{"binary":"journalctl","argv":["--facility=auth,authpriv","--grep","Failed password|Invalid user|Failed publickey|authentication failure|FAILED","--no-pager","-n","{{ args.count }}"]}},{"id":"linux.grep_log","title":"Grep a log file","summary":"Grep an extended regex (POSIX -E) against a log file under /var/log.","description":"Grep an extended regex (POSIX -E) against a log file under /var/log. Read-only. Returns matching lines with line numbers (-n) up to max_lines. Use to find recent occurrences of a specific identifier (request ID, user ID, IP) or to spot error patterns without dumping the whole file. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"low","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"pattern","type":"string","required":true,"description":"Extended regex (POSIX ERE) pattern. Passed to grep -E.","validation":{"pattern":"^.{1,512}$"}},{"name":"max_lines","type":"integer","required":false,"default":200,"description":"Cap on returned matching lines (grep -m).","validation":{"min":1,"max":2000}}],"examples":[{"title":"Recent 5xx in nginx access log","args":{"file":"/var/log/nginx/access.log","max_lines":100,"pattern":" 5[0-9][0-9] "}},{"title":"Find a request id","args":{"file":"/var/log/app/server.log","pattern":"req_abc123"}}],"search_terms":[],"command":{"binary":"grep","argv":["-E","-n","-m","{{ args.max_lines }}","-e","{{ args.pattern }}","--","{{ args.file }}"]}},{"id":"linux.hardware_summary","title":"Hardware + BIOS summary via dmidecode","summary":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","description":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","kind":"exec","risk":"low","side_effects":["One dmidecode invocation.","Read-only."],"args":[],"examples":[{"title":"System + BIOS + chassis","args":{}}],"search_terms":[],"command":{"binary":"dmidecode","argv":["-t","system","-t","bios","-t","chassis"]}},{"id":"linux.inode_usage","title":"Inode usage per filesystem","summary":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","description":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Inode usage snapshot","args":{}}],"search_terms":["out of inodes"],"command":{"binary":"df","argv":["-i","-h"]}},{"id":"linux.journalctl","title":"Recent systemd journal entries","summary":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","description":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before leaving the host.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:-]{1,128}$","max_length":128}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Recent Cassandra warnings","args":{"priority":"warning","since":"1h","unit":"cassandra"}}],"search_terms":["app crash","keeps crashing","crash loop"],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--no-pager"]}},{"id":"linux.journalctl_grep","title":"Grep recent systemd journal entries","summary":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","description":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before egress.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:-]{1,128}$","max_length":128}},{"name":"grep","type":"string","required":true,"description":"Regex pattern passed to journalctl --grep.","validation":{"pattern":"^.{1,512}$"}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Cassandra journal entries mentioning compaction","args":{"grep":"compact","since":"6h","unit":"cassandra"}},{"title":"Nginx 5xx in journal","args":{"grep":" (5[0-9][0-9]) ","priority":"notice","unit":"nginx"}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--grep","{{ args.grep }}","--no-pager"]}},{"id":"linux.kernel_modules","title":"Loaded kernel modules sorted by size","summary":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","description":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","kind":"exec","risk":"low","side_effects":["One lsmod invocation.","Read-only."],"args":[],"examples":[{"title":"Largest loaded modules","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lsmod | sort -k 3 -n -r | head -30"]}},{"id":"linux.last_logins","title":"Recent successful logins","summary":"Show the last N successful logins via `last`. Depending on the distribution, `last` reads the legacy wtmp file or the wtmpdb login-history database. Shows user, terminal, source IP, and duration. Read-only.","description":"Show the last N successful logins via `last`. Depending on the distribution, `last` reads the legacy wtmp file or the wtmpdb login-history database. Shows user, terminal, source IP, and duration. Read-only.","kind":"exec","risk":"low","side_effects":["One last invocation.","Reads the host's login-history database (legacy wtmp or wtmpdb)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent logins to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 successful logins","args":{}}],"search_terms":[],"command":{"binary":"last","argv":["-F","-n","{{ args.count }}"]}},{"id":"linux.lvm_status","title":"LVM volume / group / PV summary","summary":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","description":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","kind":"exec","risk":"low","side_effects":["Three LVM CLI invocations.","Read-only."],"args":[],"examples":[{"title":"LVM snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lvs; echo; vgs; echo; pvs"]}},{"id":"linux.mdadm_status","title":"mdadm RAID array status","summary":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","description":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","kind":"exec","risk":"low","side_effects":["One cat + one mdadm --detail per array.","Read-only."],"args":[],"examples":[{"title":"Array health snapshot","args":{}}],"search_terms":["raid rebuild","raid degraded","failed drive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/mdstat; for md in /dev/md[0-9]*; do [ -e \"$md\" ] || continue; echo; mdadm --detail \"$md\"; done"]}},{"id":"linux.memory","title":"System memory snapshot","summary":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","description":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","kind":"exec","risk":"low","side_effects":["Reads /proc/meminfo via the free utility.","Touches no files."],"args":[],"examples":[{"title":"Snapshot memory","args":{}}],"search_terms":[],"command":{"binary":"free","argv":["-m"]}},{"id":"linux.memory_detailed","title":"Full /proc/meminfo","summary":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","description":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","kind":"exec","risk":"low","side_effects":["One read of /proc/meminfo.","Read-only."],"args":[],"examples":[{"title":"Full memory accounting","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/meminfo"]}},{"id":"linux.mount_status","title":"Mounted filesystems","summary":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","description":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","kind":"exec","risk":"low","side_effects":["One findmnt invocation.","Read-only."],"args":[],"examples":[{"title":"All mounted filesystems","args":{}}],"search_terms":["read only filesystem"],"command":{"binary":"/bin/sh","argv":["-c","findmnt -A"]}},{"id":"linux.network_interfaces","title":"Network interfaces","summary":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","description":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"All interfaces (JSON)","args":{}}],"search_terms":["link down","ifconfig"],"command":{"binary":"ip","argv":["-j","addr","show"]}},{"id":"linux.network_routes","title":"Routing table + policy rules","summary":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","description":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","kind":"exec","risk":"low","side_effects":["Three ip invocations.","Read-only."],"args":[],"examples":[{"title":"All routes","args":{}}],"search_terms":["default gateway","no route to host"],"command":{"binary":"/bin/sh","argv":["-c","ip route show; echo; ip rule show; echo; ip -6 route show"]}},{"id":"linux.os_release","title":"Distro + kernel identity","summary":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","description":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","kind":"exec","risk":"low","side_effects":["Two file/utility reads.","Read-only."],"args":[],"examples":[{"title":"Distro + kernel","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/os-release; echo; uname -a"]}},{"id":"linux.reboot_host","title":"Schedule a host reboot","summary":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","description":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","kind":"exec","risk":"critical","side_effects":["Wall message broadcast to all logged-in users.","One-minute timer set; kernel shutdown begins after.","Every running service stops; all open connections drop."],"args":[{"name":"note","type":"string","required":true,"description":"Message broadcast to logged-in users in the reboot warning.","validation":{"pattern":"^[a-zA-Z0-9 .,_:;/\\-]{4,200}$"}}],"examples":[{"title":"Reboot for kernel upgrade","args":{"note":"kernel upgrade to 5.15.140 - pending /var/run/reboot-required"}}],"search_terms":["restart host","reboot box","restart server"],"command":{"binary":"shutdown","argv":["-r","+1","emisar-initiated reboot: {{ args.note }}"]}},{"id":"linux.sudoers_dump","title":"sudoers configuration audit","summary":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","description":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /etc/sudoers and ls of /etc/sudoers.d/.","Requires root or sudo-readable perms."],"args":[],"examples":[{"title":"Sudoers audit","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/sudoers 2>/dev/null; echo; ls -la /etc/sudoers.d/ 2>/dev/null"]}},{"id":"linux.systemctl_disable","title":"Disable a systemd unit at boot","summary":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","description":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Removes symlinks under /etc/systemd/system/.","Idempotent."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Disable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["disable","{{ args.unit }}"]}},{"id":"linux.systemctl_enable","title":"Enable a systemd unit at boot","summary":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","description":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Creates symlinks under /etc/systemd/system/.","Idempotent — re-running on an already-enabled unit is a no-op."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Enable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["enable","{{ args.unit }}"]}},{"id":"linux.systemctl_reload","title":"Reload a systemd unit's config","summary":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","description":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","kind":"exec","risk":"high","side_effects":["Sends SIGHUP (or the configured reload signal) to the unit.","Unit re-reads its config; existing workers continue."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Reload nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"linux.systemctl_restart","title":"Restart a systemd unit","summary":"Restart a named systemd unit.","description":"Restart a named systemd unit. Clients will see an outage of seconds-to-minutes depending on the unit. Treat as a last-resort action: prefer diagnosis (logs, status, disk, memory) first. Never restart a database under load without confirming there is no in-flight repair, compaction, or similar background operation. WHICH units this runner may restart is an operator policy decision (high-risk → require_approval by default), not a fixed list; the unit is bounded to a valid systemd unit name so it can't carry shell metacharacters.","kind":"exec","risk":"high","side_effects":["Stops the named unit, then starts it.","Disconnects existing clients of the unit.","May trigger downstream alerts if the unit takes time to recover.","Does not modify configuration or on-disk state."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to restart (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:][A-Za-z0-9@._:-]{0,127}$","max_length":128}}],"examples":[{"title":"Restart nginx after a config reload check","args":{"unit":"nginx"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"linux.systemctl_start","title":"Start a systemd unit","summary":"`systemctl start <unit>`. Brings a unit up. The unit name is pattern-restricted to safe systemd unit naming. Combine with `linux.systemctl_status` afterward to confirm the unit reached active state.","description":"`systemctl start <unit>`. Brings a unit up. The unit name is pattern-restricted to safe systemd unit naming. Combine with `linux.systemctl_status` afterward to confirm the unit reached active state.","kind":"exec","risk":"high","side_effects":["Starts the unit (and any required dependencies).","Triggers ExecStartPre/Post hooks declared in the unit."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Start nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","--no-block","{{ args.unit }}"]}},{"id":"linux.systemctl_status","title":"Systemd unit status","summary":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","description":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","kind":"exec","risk":"low","side_effects":["Reads systemd state.","Touches no files."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to query.","validation":{"pattern":"^[a-zA-Z0-9@._][a-zA-Z0-9@._-]{0,127}$"}}],"examples":[{"title":"Check Cassandra status","args":{"unit":"cassandra"}}],"search_terms":["service won't start","unit down","not running"],"command":{"binary":"systemctl","argv":["status","{{ args.unit }}","--no-pager"]}},{"id":"linux.systemctl_stop","title":"Stop a systemd unit","summary":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","description":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","kind":"exec","risk":"high","side_effects":["SIGTERMs (then SIGKILLs) the unit's processes.","Triggers ExecStop/ExecStopPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Stop nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","--no-block","{{ args.unit }}"]}},{"id":"linux.tail_log","title":"Tail a log file","summary":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","description":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"low","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines to return (tail -n).","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 lines of nginx error log","args":{"file":"/var/log/nginx/error.log","lines":100}},{"title":"Last 500 lines of an app log","args":{"file":"/var/log/app/server.log","lines":500}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","{{ args.file }}"]}},{"id":"linux.uptime","title":"System uptime and load average","summary":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","description":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","kind":"exec","risk":"low","side_effects":["Reads /proc/loadavg and /proc/uptime via the uptime utility.","Touches no files."],"args":[],"examples":[{"title":"Get uptime and load","args":{}}],"search_terms":["last reboot"],"command":{"binary":"uptime","argv":[]}},{"id":"linux.who_now","title":"Currently logged-in users","summary":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","description":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","kind":"exec","risk":"low","side_effects":["Two utility invocations.","Read-only."],"args":[],"examples":[{"title":"Current logins","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","who; echo; w"]}}]},{"version":"0.4.0","content_hash":"sha256:7931dfd81e602be495c0015d9b5ab7ad8dc62c52704d84f45d4590cc3aba8478","tarball_url":"https://registry.emisar.dev/v1/packs/linux-core/0.4.0/7931dfd81e602be495c0015d9b5ab7ad8dc62c52704d84f45d4590cc3aba8478/pack.tar.gz","actions":[{"id":"linux.arp_neighbors","title":"ARP / IPv6 neighbor table","summary":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","description":"`ip neigh show` — every known L2 neighbor with state (REACHABLE, STALE, FAILED). Useful for diagnosing intermittent L2 reachability problems. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[],"command":{"binary":"ip","argv":["neigh","show"]}},{"id":"linux.cpu_info","title":"CPU topology and features","summary":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","description":"`lscpu` output — sockets, cores per socket, threads per core, architecture, microarchitecture, MHz, cache sizes, vulnerabilities (Spectre/Meltdown mitigation state). Use to confirm a host's CPU matches what the workload assumes. Read-only.","kind":"exec","risk":"low","side_effects":["One lscpu invocation.","Read-only."],"args":[],"examples":[{"title":"CPU layout + features","args":{}}],"search_terms":[],"command":{"binary":"lscpu","argv":[]}},{"id":"linux.cron_recent","title":"Recent cron job execution log","summary":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show last N journalctl entries matching CRON. Lets operators see \"did the backup job fire last night?\" without grepping syslog. Read-only. CRON log lines include the executed command lines (`CMD (…)`), which routinely carry inline credentials — the same exposure as `linux.crontab_all`; the runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One journalctl invocation.","Read-only, but exposes cron command lines (may include inline secrets)."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent CRON entries to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 cron entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -u cron -u crond -t CRON -t CROND --no-pager -n {{ args.count }}"]}},{"id":"linux.crontab_all","title":"All user crontabs + system cron dirs","summary":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump every per-user crontab AND the system cron dirs (/etc/crontab, /etc/cron.d/, /etc/cron.{hourly,daily,weekly,monthly}/). Use to answer \"what's scheduled on this host?\" Read-only. Cron command lines routinely carry inline credentials (a `curl` bearer token, a `mysql -p<pw>`), so this can surface secrets. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Iterates user crontabs + reads /etc/cron.*.","Read-only, but requires root and exposes cron command lines (may include inline secrets)."],"args":[],"examples":[{"title":"Every scheduled job on this host","args":{}}],"search_terms":["scheduled jobs","scheduled tasks"],"command":{"binary":"/bin/sh","argv":["-c","for u in $(getent passwd | awk -F: '$7 !~ /nologin|false/ {print $1}'); do echo \"--- crontab -u $u ---\"; crontab -l -u \"$u\" 2>/dev/null; done; echo '--- /etc/crontab ---'; cat /etc/crontab 2>/dev/null; echo '--- /etc/cron.d/ ---'; ls -la /etc/cron.d/ 2>/dev/null; for d in hourly daily weekly monthly; do echo \"--- /etc/cron.$d/ ---\"; ls -la \"/etc/cron.$d/\" 2>/dev/null; done"]}},{"id":"linux.disk_smart","title":"SMART health for one disk","summary":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","description":"Run `smartctl -H -A` against a block device. Returns the overall PASS/FAIL plus the attribute table (reallocated sectors, pending, uncorrectable, temperature). Read-only on the disk; needs the `smartmontools` package and CAP_SYS_RAWIO (root) to access device registers. For a disk behind a RAID controller (Dell PERC, HP SmartArray), pass `device_type` (e.g. `megaraid,0`) — the bare block device isn't reachable through the controller without it.","kind":"exec","risk":"low","side_effects":["One smartctl invocation.","Reads SMART registers; no writes to the disk."],"args":[{"name":"device","type":"string","required":true,"description":"Block device under /dev (e.g. sda, nvme0n1).","validation":{"pattern":"^[a-zA-Z0-9]{1,16}$"}},{"name":"device_type","type":"string","required":false,"default":"auto","description":"smartctl device type (-d). \"auto\" (default) auto-detects direct ATA/SATA/NVMe disks; use \"megaraid,N\" or \"cciss,N\" for a disk behind a RAID controller, or \"sat\"/\"scsi\"/\"nvme\" to force a transport.","validation":{"pattern":"^(auto|ata|sat|scsi|nvme|megaraid,[0-9]{1,3}|cciss,[0-9]{1,3}|aacraid,[0-9]{1,3},[0-9]{1,3},[0-9]{1,3})$","max_length":32}}],"examples":[{"title":"SMART for sda (direct)","args":{"device":"sda"}},{"title":"SMART for a disk behind a PERC / megaraid controller","args":{"device":"sda","device_type":"megaraid,0"}}],"search_terms":["failing drive","bad sectors"],"command":{"binary":"smartctl","argv":["-d","{{ args.device_type }}","-H","-A","/dev/{{ args.device }}"]}},{"id":"linux.disk_usage","title":"Filesystem disk usage","summary":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","description":"Report filesystem usage for the supplied paths using df. Read-only. Use this to assess disk pressure before recommending cleanup, repair, compaction tuning, or adding disk. If a filesystem is >85% full, surface it but do not silently delete or truncate data — that's a separate, approval-gated action.","kind":"exec","risk":"low","side_effects":["Reads filesystem metadata via df.","Touches no files.","Does not mount, unmount, or modify anything."],"args":[{"name":"paths","type":"string_array","required":false,"default":["/"],"description":"One or more paths to inspect. Each path is passed to df -P -h.","validation":{"allowed_prefixes":["/","/var","/tmp","/home","/usr","/opt"],"max_items":8}}],"examples":[{"title":"Check root filesystem usage","args":{}},{"title":"Check /var and /tmp","args":{"paths":["/var","/tmp"]}}],"search_terms":["no space left on device","out of space"],"command":{"binary":"df","argv":["-P","-h","{{ args.paths }}"]}},{"id":"linux.failed_logins","title":"Recent failed login attempts","summary":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","description":"List recent failed authentication attempts from the systemd journal — sshd's \"Failed password\" / \"Invalid user\" plus pam_unix \"authentication failure\" from su/sudo/login. High-signal for \"is this host being brute-forced?\" Read-only, but flagged medium-risk: the source IPs and usernames are sensitive PII. A healthy host with no failed auth returns nothing (the journal query exits 1 on no match, which is treated as success).","kind":"exec","risk":"medium","side_effects":["One journalctl read of the auth/authpriv journal (root or the systemd-journal group).","Output includes source IPs and usernames (PII).","Read-only."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many of the most recent failed attempts to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 failed login attempts","args":{}}],"search_terms":["under attack","intrusion","brute force","break-in","hacked"],"command":{"binary":"journalctl","argv":["--facility=auth,authpriv","--grep","Failed password|Invalid user|Failed publickey|authentication failure|FAILED","--no-pager","-n","{{ args.count }}"]}},{"id":"linux.grep_log","title":"Grep a log file","summary":"Grep an extended regex (POSIX -E) against a log file under /var/log.","description":"Grep an extended regex (POSIX -E) against a log file under /var/log. Read-only. Returns matching lines with line numbers (-n) up to max_lines. Use to find recent occurrences of a specific identifier (request ID, user ID, IP) or to spot error patterns without dumping the whole file. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"low","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"pattern","type":"string","required":true,"description":"Extended regex (POSIX ERE) pattern. Passed to grep -E.","validation":{"pattern":"^.{1,512}$"}},{"name":"max_lines","type":"integer","required":false,"default":200,"description":"Cap on returned matching lines (grep -m).","validation":{"min":1,"max":2000}}],"examples":[{"title":"Recent 5xx in nginx access log","args":{"file":"/var/log/nginx/access.log","max_lines":100,"pattern":" 5[0-9][0-9] "}},{"title":"Find a request id","args":{"file":"/var/log/app/server.log","pattern":"req_abc123"}}],"search_terms":[],"command":{"binary":"grep","argv":["-E","-n","-m","{{ args.max_lines }}","-e","{{ args.pattern }}","--","{{ args.file }}"]}},{"id":"linux.hardware_summary","title":"Hardware + BIOS summary via dmidecode","summary":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","description":"`dmidecode` system + bios + chassis sections. Vendor, model, serial, BIOS version, manufacturing date. Required root (read-only on SMBIOS). Useful when correlating hardware-class to OS-class incidents. dmidecode reads SMBIOS — absent on containers and many cloud VMs, where this fails command-not-found; expect it on bare metal or VMs with SMBIOS passthrough.","kind":"exec","risk":"low","side_effects":["One dmidecode invocation.","Read-only."],"args":[],"examples":[{"title":"System + BIOS + chassis","args":{}}],"search_terms":[],"command":{"binary":"dmidecode","argv":["-t","system","-t","bios","-t","chassis"]}},{"id":"linux.inode_usage","title":"Inode usage per filesystem","summary":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","description":"Show inode usage per filesystem (`df -i`). A \"disk full\" report that doesn't match `df -h` is almost always inode exhaustion — this surfaces it directly. Read-only.","kind":"exec","risk":"low","side_effects":["One df invocation.","Read-only."],"args":[],"examples":[{"title":"Inode usage snapshot","args":{}}],"search_terms":["out of inodes"],"command":{"binary":"df","argv":["-i","-h"]}},{"id":"linux.journalctl","title":"Recent systemd journal entries","summary":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","description":"Read recent systemd journal entries for a named unit, filtered by priority and a time window. Use to triage service errors. Logs may reveal sensitive identifiers, IPs, hostnames, or PII; treat output as confidential. Do not echo verbatim to end users without consideration.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before leaving the host.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:-]{1,128}$","max_length":128}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Recent Cassandra warnings","args":{"priority":"warning","since":"1h","unit":"cassandra"}}],"search_terms":["app crash","keeps crashing","crash loop"],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--no-pager"]}},{"id":"linux.journalctl_grep","title":"Grep recent systemd journal entries","summary":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","description":"Like linux.journalctl, but filters entries to those matching a regex (via journalctl --grep). Read-only. Use when you already know the rough identifier or substring you're looking for (request ID, hostname, IP, error string) and don't want to download a large unfiltered journal slice. Output is run through the runner's redactor before leaving the host.","kind":"exec","risk":"medium","side_effects":["Reads service logs which may contain operational secrets.","Output is run through the runner's redactor before egress.","Does not modify anything."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name to inspect (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:-]{1,128}$","max_length":128}},{"name":"grep","type":"string","required":true,"description":"Regex pattern passed to journalctl --grep.","validation":{"pattern":"^.{1,512}$"}},{"name":"since","type":"duration","required":false,"default":"2h","description":"Look back at most this far.","validation":{"max_duration":"24h0m0s"}},{"name":"priority","type":"string","required":false,"default":"warning","description":"Minimum priority level for entries.","validation":{"enum":["debug","info","notice","warning","err","crit","alert","emerg"]}}],"examples":[{"title":"Cassandra journal entries mentioning compaction","args":{"grep":"compact","since":"6h","unit":"cassandra"}},{"title":"Nginx 5xx in journal","args":{"grep":" (5[0-9][0-9]) ","priority":"notice","unit":"nginx"}}],"search_terms":[],"command":{"binary":"journalctl","argv":["-u","{{ args.unit }}","--since","{{ args.since }} ago","-p","{{ args.priority }}","--grep","{{ args.grep }}","--no-pager"]}},{"id":"linux.kernel_modules","title":"Loaded kernel modules sorted by size","summary":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","description":"`lsmod` sorted by size, top 30. Useful to spot unexpected modules loaded on a production host (rootkits, debug tooling, vendor drivers). Read-only.","kind":"exec","risk":"low","side_effects":["One lsmod invocation.","Read-only."],"args":[],"examples":[{"title":"Largest loaded modules","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lsmod | sort -k 3 -n -r | head -30"]}},{"id":"linux.last_logins","title":"Recent successful logins","summary":"Show last N successful logins from /var/log/wtmp via `last`. Shows user, terminal, source IP, duration. Read-only.","description":"Show last N successful logins from /var/log/wtmp via `last`. Shows user, terminal, source IP, duration. Read-only.","kind":"exec","risk":"low","side_effects":["One last invocation.","Reads /var/log/wtmp."],"args":[{"name":"count","type":"integer","required":false,"default":50,"description":"How many recent logins to return.","validation":{"min":1,"max":500}}],"examples":[{"title":"Last 50 successful logins","args":{}}],"search_terms":[],"command":{"binary":"last","argv":["-F","-n","{{ args.count }}"]}},{"id":"linux.lvm_status","title":"LVM volume / group / PV summary","summary":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","description":"Run `lvs && vgs && pvs` for a one-shot LVM topology snapshot. Logical volumes, volume groups, physical volumes — sizes, free space, attributes. Read-only. Needs LVM tools installed.","kind":"exec","risk":"low","side_effects":["Three LVM CLI invocations.","Read-only."],"args":[],"examples":[{"title":"LVM snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","lvs; echo; vgs; echo; pvs"]}},{"id":"linux.mdadm_status","title":"mdadm RAID array status","summary":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","description":"Read /proc/mdstat plus `mdadm --detail` for every active array. Surfaces array state, devices, sync progress, faults. Read-only. Returns \"no arrays\" cleanly when there's no mdadm RAID configured.","kind":"exec","risk":"low","side_effects":["One cat + one mdadm --detail per array.","Read-only."],"args":[],"examples":[{"title":"Array health snapshot","args":{}}],"search_terms":["raid rebuild","raid degraded","failed drive"],"command":{"binary":"/bin/sh","argv":["-c","cat /proc/mdstat; for md in /dev/md[0-9]*; do [ -e \"$md\" ] || continue; echo; mdadm --detail \"$md\"; done"]}},{"id":"linux.memory","title":"System memory snapshot","summary":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","description":"Report memory and swap usage via free -m. Read-only, single sample. Memory state fluctuates between consecutive calls; take two samples a few seconds apart before drawing conclusions about pressure.","kind":"exec","risk":"low","side_effects":["Reads /proc/meminfo via the free utility.","Touches no files."],"args":[],"examples":[{"title":"Snapshot memory","args":{}}],"search_terms":[],"command":{"binary":"free","argv":["-m"]}},{"id":"linux.memory_detailed","title":"Full /proc/meminfo","summary":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","description":"Dump full /proc/meminfo. More detail than the `linux.memory` action — surfaces hugepages, slab, dirty/writeback, page tables, KSM, cgroup memcg. Read-only.","kind":"exec","risk":"low","side_effects":["One read of /proc/meminfo.","Read-only."],"args":[],"examples":[{"title":"Full memory accounting","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/meminfo"]}},{"id":"linux.mount_status","title":"Mounted filesystems","summary":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","description":"List every mounted filesystem with type, source device, mountpoint, and mount options. Read-only. Use to confirm a service has the right disk attached or to find a stuck/duplicate mount.","kind":"exec","risk":"low","side_effects":["One findmnt invocation.","Read-only."],"args":[],"examples":[{"title":"All mounted filesystems","args":{}}],"search_terms":["read only filesystem"],"command":{"binary":"/bin/sh","argv":["-c","findmnt -A"]}},{"id":"linux.network_interfaces","title":"Network interfaces","summary":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","description":"`ip -j addr show` JSON. Returns every interface with its addresses, state, MAC, MTU. Use to confirm an interface is up with the right IP. Read-only.","kind":"exec","risk":"low","side_effects":["One ip invocation.","Read-only."],"args":[],"examples":[{"title":"All interfaces (JSON)","args":{}}],"search_terms":["link down","ifconfig"],"command":{"binary":"ip","argv":["-j","addr","show"]}},{"id":"linux.network_routes","title":"Routing table + policy rules","summary":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","description":"`ip route show && ip rule show && ip -6 route show`. Use to debug \"why does traffic go via X instead of Y?\" — surfaces every route and policy-based routing rule. Read-only.","kind":"exec","risk":"low","side_effects":["Three ip invocations.","Read-only."],"args":[],"examples":[{"title":"All routes","args":{}}],"search_terms":["default gateway","no route to host"],"command":{"binary":"/bin/sh","argv":["-c","ip route show; echo; ip rule show; echo; ip -6 route show"]}},{"id":"linux.os_release","title":"Distro + kernel identity","summary":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","description":"Return /etc/os-release plus `uname -a`. Identifies the distribution, version, codename, and kernel. Use as a first sanity check before recommending distro-specific commands. Read-only.","kind":"exec","risk":"low","side_effects":["Two file/utility reads.","Read-only."],"args":[],"examples":[{"title":"Distro + kernel","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/os-release; echo; uname -a"]}},{"id":"linux.reboot_host","title":"Schedule a host reboot","summary":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","description":"Schedule a reboot via `shutdown -r +1` — one-minute warning to give in-flight connections a chance to drain. Sends a wall message with the operator-supplied reason. Cannot be undone except by `shutdown -c` BEFORE the minute elapses; once the kernel begins shutdown the host is going down regardless.","kind":"exec","risk":"critical","side_effects":["Wall message broadcast to all logged-in users.","One-minute timer set; kernel shutdown begins after.","Every running service stops; all open connections drop."],"args":[{"name":"note","type":"string","required":true,"description":"Message broadcast to logged-in users in the reboot warning.","validation":{"pattern":"^[a-zA-Z0-9 .,_:;/\\-]{4,200}$"}}],"examples":[{"title":"Reboot for kernel upgrade","args":{"note":"kernel upgrade to 5.15.140 - pending /var/run/reboot-required"}}],"search_terms":["restart host","reboot box","restart server"],"command":{"binary":"shutdown","argv":["-r","+1","emisar-initiated reboot: {{ args.note }}"]}},{"id":"linux.sudoers_dump","title":"sudoers configuration audit","summary":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","description":"Dump /etc/sudoers and the index of /etc/sudoers.d/. Use for an audit pass — \"who can sudo to what?\". Output is the host's privilege-escalation policy — security-sensitive recon, but sudoers stores rules, never credentials. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /etc/sudoers and ls of /etc/sudoers.d/.","Requires root or sudo-readable perms."],"args":[],"examples":[{"title":"Sudoers audit","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cat /etc/sudoers 2>/dev/null; echo; ls -la /etc/sudoers.d/ 2>/dev/null"]}},{"id":"linux.systemctl_disable","title":"Disable a systemd unit at boot","summary":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","description":"`systemctl disable <unit>`. Removes the boot symlinks. Does NOT stop the unit now — pair with `linux.systemctl_stop` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Removes symlinks under /etc/systemd/system/.","Idempotent."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Disable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["disable","{{ args.unit }}"]}},{"id":"linux.systemctl_enable","title":"Enable a systemd unit at boot","summary":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","description":"`systemctl enable <unit>`. Creates the symlinks so the unit starts at boot. Does NOT start it now — pair with `linux.systemctl_start` for that. Persistent change across reboots.","kind":"exec","risk":"high","side_effects":["Creates symlinks under /etc/systemd/system/.","Idempotent — re-running on an already-enabled unit is a no-op."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Enable nginx at boot","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["enable","{{ args.unit }}"]}},{"id":"linux.systemctl_reload","title":"Reload a systemd unit's config","summary":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","description":"`systemctl reload <unit>`. The unit re-reads its config without restarting (works only for units declaring an ExecReload). Use after editing nginx.conf / postgresql.conf / etc. The reload is graceful by definition — no requests dropped.","kind":"exec","risk":"high","side_effects":["Sends SIGHUP (or the configured reload signal) to the unit.","Unit re-reads its config; existing workers continue."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Reload nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"linux.systemctl_restart","title":"Restart a systemd unit","summary":"Restart a named systemd unit.","description":"Restart a named systemd unit. Clients will see an outage of seconds-to-minutes depending on the unit. Treat as a last-resort action: prefer diagnosis (logs, status, disk, memory) first. Never restart a database under load without confirming there is no in-flight repair, compaction, or similar background operation. WHICH units this runner may restart is an operator policy decision (high-risk → require_approval by default), not a fixed list; the unit is bounded to a valid systemd unit name so it can't carry shell metacharacters.","kind":"exec","risk":"high","side_effects":["Stops the named unit, then starts it.","Disconnects existing clients of the unit.","May trigger downstream alerts if the unit takes time to recover.","Does not modify configuration or on-disk state."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to restart (e.g. nginx, nomad, consul.service, foo@bar.service).","validation":{"pattern":"^[A-Za-z0-9@._:][A-Za-z0-9@._:-]{0,127}$","max_length":128}}],"examples":[{"title":"Restart nginx after a config reload check","args":{"unit":"nginx"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"linux.systemctl_start","title":"Start a systemd unit","summary":"`systemctl start <unit>`. Brings a unit up. The unit name is pattern-restricted to safe systemd unit naming. Combine with `linux.systemctl_status` afterward to confirm the unit reached active state.","description":"`systemctl start <unit>`. Brings a unit up. The unit name is pattern-restricted to safe systemd unit naming. Combine with `linux.systemctl_status` afterward to confirm the unit reached active state.","kind":"exec","risk":"high","side_effects":["Starts the unit (and any required dependencies).","Triggers ExecStartPre/Post hooks declared in the unit."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Start nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","--no-block","{{ args.unit }}"]}},{"id":"linux.systemctl_status","title":"Systemd unit status","summary":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","description":"Report the current systemd unit status for a named service. Read-only. Use to confirm whether a service is active before recommending diagnostic or remediation actions.","kind":"exec","risk":"low","side_effects":["Reads systemd state.","Touches no files."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit to query.","validation":{"pattern":"^[a-zA-Z0-9@._][a-zA-Z0-9@._-]{0,127}$"}}],"examples":[{"title":"Check Cassandra status","args":{"unit":"cassandra"}}],"search_terms":["service won't start","unit down","not running"],"command":{"binary":"systemctl","argv":["status","{{ args.unit }}","--no-pager"]}},{"id":"linux.systemctl_stop","title":"Stop a systemd unit","summary":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","description":"`systemctl stop <unit>`. Brings a unit down. Sends SIGTERM, waits for TimeoutStopSec, then SIGKILL. In-flight requests on the service are dropped unless the unit handles graceful drain.","kind":"exec","risk":"high","side_effects":["SIGTERMs (then SIGKILLs) the unit's processes.","Triggers ExecStop/ExecStopPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Systemd unit name (e.g. nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Stop nginx","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","--no-block","{{ args.unit }}"]}},{"id":"linux.tail_log","title":"Tail a log file","summary":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","description":"Read the last N lines of a log file under /var/log. Read-only. Use to glance at the most recent activity for a service when triaging an alert, before deciding whether to grep deeper or pull more context. Output is run through the runner's redactor before it leaves the host. On journald-only hosts (no rsyslog) the system log isn't a file under /var/log — use linux.journalctl for syslog/messages; this reads on-disk files (app, nginx, …).","kind":"exec","risk":"low","side_effects":["Reads a log file under /var/log.","Output may contain operational secrets — redactor scrubs known patterns.","Does not modify anything."],"args":[{"name":"file","type":"path","required":true,"description":"Absolute path to the log file. Must be under /var/log/.","validation":{"allowed_prefixes":["/var/log/"]}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Number of trailing lines to return (tail -n).","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 lines of nginx error log","args":{"file":"/var/log/nginx/error.log","lines":100}},{"title":"Last 500 lines of an app log","args":{"file":"/var/log/app/server.log","lines":500}}],"search_terms":[],"command":{"binary":"tail","argv":["-n","{{ args.lines }}","{{ args.file }}"]}},{"id":"linux.uptime","title":"System uptime and load average","summary":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","description":"Report system uptime and 1/5/15-minute load averages. Load averages are dimensionless and machine-dependent; compare against CPU count before interpreting them as \"high\".","kind":"exec","risk":"low","side_effects":["Reads /proc/loadavg and /proc/uptime via the uptime utility.","Touches no files."],"args":[],"examples":[{"title":"Get uptime and load","args":{}}],"search_terms":["last reboot"],"command":{"binary":"uptime","argv":[]}},{"id":"linux.who_now","title":"Currently logged-in users","summary":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","description":"`who` + `w` — usernames, terminals, login times, source IPs, and what each session is currently running. Use to confirm whether a human is on the box during an incident. Read-only.","kind":"exec","risk":"low","side_effects":["Two utility invocations.","Read-only."],"args":[],"examples":[{"title":"Current logins","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","who; echo; w"]}}]}],"retired_below":"0.3.22"},{"id":"memcached","name":"Memcached cache server","version":"0.1.7","description":"Read-only memcached introspection via the `stats` ASCII protocol — general stats, slab usage, item counts, sizes. Plus FLUSH_ALL as a critical mutator. Target host/port via MEMCACHED_HOST + MEMCACHED_PORT env vars on the runner host (default 127.0.0.1:11211).","vendor":"emisar","homepage":"https://emisar.dev/packs/memcached","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/memcached","content_hash":"sha256:d401bdb56c6835122f9b55bb03743347ddbc2745b2c90384b1deb1979800b805","tarball_url":"https://registry.emisar.dev/v1/packs/memcached/0.1.7/d401bdb56c6835122f9b55bb03743347ddbc2745b2c90384b1deb1979800b805/pack.tar.gz","requires":{"os":["linux"],"binaries":["nc"]},"detect":{"binaries":[],"processes":["memcached"],"ports":[11211]},"setup":{"summary":"Actions speak the memcached ASCII protocol over nc to `MEMCACHED_HOST`: `MEMCACHED_PORT` on the runner host, defaulting to the local instance at 127.0.0.1:11211. The ASCII protocol has no authentication, so no credentials are involved.","env":[{"name":"MEMCACHED_HOST","description":"Target host.","default":"127.0.0.1"},{"name":"MEMCACHED_PORT","description":"Target port.","default":"11211"}],"notes":["Any of `MEMCACHED_HOST` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","No authentication exists for this transport; reach a remote daemon only over a trusted network or tunnel.","flush_all is destructive — it invalidates every key and can stampede the origin on the next miss."],"verify":"mc.stats"},"actions":[{"id":"mc.flush_all","title":"flush_all","summary":"Invalidate every key. Cold cache → origin load spike.","description":"Invalidate every key. Cold cache → origin load spike.","kind":"exec","risk":"critical","side_effects":["Every key becomes invalid immediately.","First miss hits origin for every cached value."],"args":[],"examples":[{"title":"Flush all","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'flush_all\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats","title":"stats (general)","summary":"Show uptime, current connections, get/set rates, hit/miss, bytes, evictions.","description":"Show uptime, current connections, get/set rates, hit/miss, bytes, evictions.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_items","title":"stats items","summary":"Show per-slab item counts + age.","description":"Show per-slab item counts + age.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Items","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats items\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_settings","title":"stats settings","summary":"Show daemon configuration at boot.","description":"Show daemon configuration at boot.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats settings\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_sizes","title":"stats sizes","summary":"Show a histogram of item sizes. WARNING: scans all items — can be slow on busy servers.","description":"Show a histogram of item sizes. WARNING: scans all items — can be slow on busy servers.","kind":"exec","risk":"low","side_effects":["Scans every item — high latency hit on busy servers.","Read-only."],"args":[],"examples":[{"title":"Size histogram","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats sizes\\nquit\\n' | nc -w 30 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_slabs","title":"stats slabs","summary":"Show per-slab allocation + utilization.","description":"Show per-slab allocation + utilization.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Slabs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats slabs\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.version","title":"version","summary":"Show the daemon version.","description":"Show the daemon version.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'version\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}}],"previous_versions":[{"version":"0.1.5","content_hash":"sha256:4b06eb0982b07b530db4acb9c5a2fe90acc8561c43c750ed68dce570d6b320a4","tarball_url":"https://registry.emisar.dev/v1/packs/memcached/0.1.5/4b06eb0982b07b530db4acb9c5a2fe90acc8561c43c750ed68dce570d6b320a4/pack.tar.gz","actions":[{"id":"mc.flush_all","title":"flush_all","summary":"Invalidate every key. Cold cache → origin load spike.","description":"Invalidate every key. Cold cache → origin load spike.","kind":"exec","risk":"critical","side_effects":["Every key becomes invalid immediately.","First miss hits origin for every cached value."],"args":[],"examples":[{"title":"Flush all","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'flush_all\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats","title":"stats (general)","summary":"Show uptime, current connections, get/set rates, hit/miss, bytes, evictions.","description":"Show uptime, current connections, get/set rates, hit/miss, bytes, evictions.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_items","title":"stats items","summary":"Show per-slab item counts + age.","description":"Show per-slab item counts + age.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Items","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats items\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_settings","title":"stats settings","summary":"Show daemon configuration at boot.","description":"Show daemon configuration at boot.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats settings\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_sizes","title":"stats sizes","summary":"Show a histogram of item sizes. WARNING: scans all items — can be slow on busy servers.","description":"Show a histogram of item sizes. WARNING: scans all items — can be slow on busy servers.","kind":"exec","risk":"low","side_effects":["Scans every item — high latency hit on busy servers.","Read-only."],"args":[],"examples":[{"title":"Size histogram","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats sizes\\nquit\\n' | nc -w 30 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_slabs","title":"stats slabs","summary":"Show per-slab allocation + utilization.","description":"Show per-slab allocation + utilization.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Slabs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats slabs\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.version","title":"version","summary":"Show the daemon version.","description":"Show the daemon version.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'version\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}}]},{"version":"0.1.4","content_hash":"sha256:d930b616eb5929a01f5771a010a09feb7a80374be61f9a1fb48af1b45916b147","tarball_url":"https://registry.emisar.dev/v1/packs/memcached/0.1.4/d930b616eb5929a01f5771a010a09feb7a80374be61f9a1fb48af1b45916b147/pack.tar.gz","actions":[{"id":"mc.flush_all","title":"flush_all","summary":"Invalidates every key. Cold cache → origin load spike.","description":"Invalidates every key. Cold cache → origin load spike.","kind":"exec","risk":"critical","side_effects":["Every key becomes invalid immediately.","First miss hits origin for every cached value."],"args":[],"examples":[{"title":"Flush all","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'flush_all\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats","title":"stats (general)","summary":"Show uptime, current connections, get/set rates, hit/miss, bytes, evictions.","description":"Show uptime, current connections, get/set rates, hit/miss, bytes, evictions.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_items","title":"stats items","summary":"Show per-slab item counts + age.","description":"Show per-slab item counts + age.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Items","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats items\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_settings","title":"stats settings","summary":"Show daemon configuration at boot.","description":"Show daemon configuration at boot.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Settings","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats settings\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_sizes","title":"stats sizes","summary":"Show a histogram of item sizes. WARNING: scans all items — can be slow on busy servers.","description":"Show a histogram of item sizes. WARNING: scans all items — can be slow on busy servers.","kind":"exec","risk":"low","side_effects":["Scans every item — high latency hit on busy servers.","Read-only."],"args":[],"examples":[{"title":"Size histogram","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats sizes\\nquit\\n' | nc -w 30 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.stats_slabs","title":"stats slabs","summary":"Show per-slab allocation + utilization.","description":"Show per-slab allocation + utilization.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Slabs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'stats slabs\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}},{"id":"mc.version","title":"version","summary":"Show the daemon version.","description":"Show the daemon version.","kind":"exec","risk":"low","side_effects":["One ASCII protocol call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","printf 'version\\nquit\\n' | nc -w 5 \"${MEMCACHED_HOST:-127.0.0.1}\" \"${MEMCACHED_PORT:-11211}\""]}}]}]},{"id":"minio","name":"MinIO operations","version":"0.1.19","description":"Cluster + bucket + user introspection plus operator surface (user enable/disable, bucket heal, cluster service restart). Talks to mc CLI configured via MC_HOST_<alias> env var on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/minio","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/minio","content_hash":"sha256:2fccb05171ea06d3ef70cd8e38923a795e7474f619ac165b79b1143f039cdaf7","tarball_url":"https://registry.emisar.dev/v1/packs/minio/0.1.19/2fccb05171ea06d3ef70cd8e38923a795e7474f619ac165b79b1143f039cdaf7/pack.tar.gz","requires":{"os":["linux"],"binaries":["mc"]},"detect":{"binaries":[],"processes":["minio"],"ports":[]},"setup":{"summary":"Actions run the mc client against an alias passed as an argument. mc reads that alias from an MC_HOST_<alias> env var of the form https://ACCESS:SECRET@endpoint on the runner host — no on-disk mc config needed.","env":[{"name":"MC_HOST_minio","required":true,"description":"Connection for the \"minio\" alias, as https://ACCESS_KEY:SECRET_KEY@endpoint. Rename the suffix to match the alias you pass.","example":"https://minioadmin:minioadmin@minio.internal:9000"}],"notes":["Create the access/secret pair with mc admin user add <alias> <access-key> <secret-key>, or in the MinIO Console under Identity → Users; attach the readonly policy for the read actions and consoleAdmin for the admin-* ones.","The MC_HOST_<alias> you set (e.g. `MC_HOST_minio`) must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","The env var suffix must exactly match the alias argument: actions whose examples pass alias \"minio\" need `MC_HOST_minio`; a different alias needs MC_HOST_<that-alias>.","The access/secret pair needs admin permissions for the admin-* actions (info, user list/enable/disable, heal, service restart); a plain user key can only list buckets and stat."],"verify":"minio.admin_info"},"actions":[{"id":"minio.admin_info","title":"mc admin info","summary":"Show cluster info: nodes, storage, network, uptime.","description":"Show cluster info: nodes, storage, network, uptime.","kind":"exec","risk":"low","side_effects":["One admin call.","Read-only."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias for the cluster.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Cluster info","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","info","{{ args.alias }}","--json"]}},{"id":"minio.admin_top_locks","title":"mc admin top locks","summary":"List the top object locks held across the cluster — spots stuck operations.","description":"List the top object locks held across the cluster — spots stuck operations.","kind":"exec","risk":"low","side_effects":["One admin call.","Read-only."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Top locks","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","top","locks","{{ args.alias }}"]}},{"id":"minio.admin_trace","title":"mc admin trace (5s window)","summary":"Trace S3 API calls hitting the cluster for 5 seconds. Returns the one-line request summary — method, path, status, timing — never request or response headers, which carry the caller's SigV4 credential and signature.","description":"Trace S3 API calls hitting the cluster for 5 seconds. Returns the one-line request summary — method, path, status, timing — never request or response headers, which carry the caller's SigV4 credential and signature.","kind":"exec","risk":"medium","side_effects":["One admin call.","Read-only.","Returns live request paths, which name the buckets and keys clients are reading."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Trace 5s","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 mc admin trace \"${1}\" 2>&1); status=$?; printf '%s\\n' \"$out\"; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac","emisar","{{ args.alias }}"]}},{"id":"minio.bucket_stat","title":"mc du (bucket)","summary":"Show object count + size for one bucket.","description":"Show object count + size for one bucket.","kind":"exec","risk":"low","side_effects":["One scan; can be heavy on huge buckets.","Read-only."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"One bucket","args":{"alias":"minio","bucket":"backups"}}],"search_terms":[],"command":{"binary":"mc","argv":["du","{{ args.alias }}/{{ args.bucket }}"]}},{"id":"minio.heal_bucket","title":"mc admin heal -r <alias>/<bucket>","summary":"Heal one bucket recursively. Scans every object, repairs inconsistent erasure-coded shards, restores missing replicas. CPU + I/O heavy; run during low-traffic windows.","description":"Heal one bucket recursively. Scans every object, repairs inconsistent erasure-coded shards, restores missing replicas. CPU + I/O heavy; run during low-traffic windows.","kind":"exec","risk":"high","side_effects":["All objects under the bucket scanned.","Damaged shards rebuilt.","CPU + disk I/O spike for the duration of the heal."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"bucket","type":"string","required":true,"description":"Bucket name.","validation":{"pattern":"^[a-z0-9.\\-]{3,63}$"}}],"examples":[{"title":"Heal photos bucket","args":{"alias":"prod","bucket":"photos"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","heal","-r","{{ args.alias }}/{{ args.bucket }}"]}},{"id":"minio.heal_summary","title":"mc admin heal --recursive (cluster-wide)","summary":"Trigger a cluster-wide healing scan that repairs objects (not a dry-run). Does NOT use --remove. May be IO-heavy.","description":"Trigger a cluster-wide healing scan that repairs objects (not a dry-run). Does NOT use --remove. May be IO-heavy.","kind":"exec","risk":"high","side_effects":["Heavy disk + CPU during scan on each node.","May actually heal objects (not just dry-run)."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Heal cluster","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","heal","--recursive","{{ args.alias }}"]}},{"id":"minio.list_policies","title":"mc admin policy ls","summary":"List all IAM policy names.","description":"List all IAM policy names.","kind":"exec","risk":"low","side_effects":["One admin call.","Read-only."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Policies","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","policy","ls","{{ args.alias }}","--json"]}},{"id":"minio.list_users","title":"mc admin user list","summary":"List all IAM users + their status + attached policies.","description":"List all IAM users + their status + attached policies.","kind":"exec","risk":"low","side_effects":["One admin call.","Read-only."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Users","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","user","list","{{ args.alias }}","--json"]}},{"id":"minio.ls_buckets","title":"mc ls (root)","summary":"List all buckets in one alias.","description":"List all buckets in one alias.","kind":"exec","risk":"low","side_effects":["One admin call.","Read-only."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Buckets","args":{"alias":"minio"}}],"search_terms":[],"command":{"binary":"mc","argv":["ls","{{ args.alias }}","--json"]}},{"id":"minio.service_restart","title":"mc admin service restart <alias>","summary":"Restart MinIO across the cluster. Coordinated rolling restart — one node at a time so the cluster stays available. Use after a config change that requires restart.","description":"Restart MinIO across the cluster. Coordinated rolling restart — one node at a time so the cluster stays available. Use after a config change that requires restart.","kind":"exec","risk":"high","side_effects":["Rolling restart across nodes.","Brief unavailability per node; cluster-wide writes still served.","Active uploads may need retry."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Restart cluster","args":{"alias":"prod"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","service","restart","{{ args.alias }}","--json"]}},{"id":"minio.user_disable","title":"mc admin user disable","summary":"Disable one IAM user. They can't authenticate until re-enabled.","description":"Disable one IAM user. They can't authenticate until re-enabled.","kind":"exec","risk":"high","side_effects":["User can no longer authenticate.","In-flight requests by them complete."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"user","type":"string","required":true,"description":"User access key.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{2,127}$"}}],"examples":[{"title":"Disable one","args":{"alias":"minio","user":"alice"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","user","disable","{{ args.alias }}","{{ args.user }}"]}},{"id":"minio.user_enable","title":"mc admin user enable","summary":"Re-enable one IAM user; their credentials work again immediately with every policy still attached — access cut during an incident comes back.","description":"Re-enable one IAM user; their credentials work again immediately with every policy still attached — access cut during an incident comes back.","kind":"exec","risk":"high","side_effects":["User can authenticate again."],"args":[{"name":"alias","type":"string","required":true,"description":"mc alias.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"user","type":"string","required":true,"description":"User access key.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{2,127}$"}}],"examples":[{"title":"Enable one","args":{"alias":"minio","user":"alice"}}],"search_terms":[],"command":{"binary":"mc","argv":["admin","user","enable","{{ args.alias }}","{{ args.user }}"]}}],"retired_below":"0.1.19"},{"id":"mongodb","name":"MongoDB operations","version":"0.3.8","description":"Replica-set + shard-cluster introspection, slow-query identification, collection stats, plus remediation surface (killOp, replSet stepDown, collection compact, dropIndex). Authenticates via MONGO_URI env var on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/mongodb","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/mongodb","content_hash":"sha256:74920d1f2a118b2e36f55e892b8beb3d44d9be17628ad31edc9604622373c058","tarball_url":"https://registry.emisar.dev/v1/packs/mongodb/0.3.8/74920d1f2a118b2e36f55e892b8beb3d44d9be17628ad31edc9604622373c058/pack.tar.gz","requires":{"os":["linux"],"binaries":["mongosh"]},"detect":{"binaries":[],"processes":["mongod"],"ports":[27017]},"setup":{"summary":"Every action reads `MONGO_URI` from its environment and connects inside the mongosh eval (new Mongo(process.env.`MONGO_URI`)), so the host, port, replica set, auth database, and credentials all live in that single URI — and the credential never lands on mongosh's argv (/proc/<pid>/cmdline).","env":[{"name":"MONGO_URI","required":true,"description":"Full MongoDB connection string, including credentials and any auth/TLS options.","example":"mongodb://opsuser:secret@db.internal:27017/?authSource=admin&replicaSet=rs0"}],"notes":["Create the user with db.createUser({user: 'emisar', pwd: '...', roles: [{role: 'clusterMonitor', db: 'admin'}]}) on a self-managed deployment, or under Database Access → Add New Database User on Atlas.","mongosh does not read `MONGO_URI` on its own; each action connects with new Mongo(process.env.`MONGO_URI`) inside its --eval, so the user it encodes needs the privileges (clusterMonitor for reads, plus killOp/replSetStateChange/compact/dropIndex for the mutators) for the actions you enable.","Because the URI carries the credentials, it must be allowlisted in `inherit_env` for any action to reach the database."],"verify":"mongo.server_status"},"actions":[{"id":"mongo.balancer_status","title":"sh.getBalancerState()","summary":"Show whether the balancer is enabled + currently running.","description":"Show whether the balancer is enabled + currently running.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Balancer state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify({enabled:sh.getBalancerState(),running:sh.isBalancerRunning()})'"]}},{"id":"mongo.build_info","title":"buildInfo","summary":"Show server version + build flags.","description":"Show server version + build flags.","kind":"exec","risk":"low","side_effects":["One buildInfo command.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({buildInfo:1}))'"]}},{"id":"mongo.collection_list","title":"db.getCollectionNames()","summary":"List collections in one database.","description":"List collections in one database.","kind":"exec","risk":"low","side_effects":["One listCollections command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Collections in DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getCollectionNames())\"","emisar","{{ args.database }}"]}},{"id":"mongo.collection_stats","title":"db.<coll>.stats()","summary":"Show per-collection totals — count, size, storage, indexes.","description":"Show per-collection totals — count, size, storage, indexes.","kind":"exec","risk":"low","side_effects":["One collStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"One collection","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getCollection('${2}').stats())\"","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.compact_collection","title":"db.runCommand({compact:\"<coll>\"})","summary":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","description":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","kind":"exec","risk":"high","side_effects":["Collection's reads/writes blocked until compaction finishes.","Disk usage drops.","Other collections unaffected."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Compact after a large delete","args":{"collection":"events","db_name":"analytics"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('${1}').runCommand({compact: '${2}'})\"","emisar","{{ args.db_name }}","{{ args.collection }}"]}},{"id":"mongo.concurrent_transactions","title":"Read/write tickets (concurrency saturation)","summary":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","description":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Ticket pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=db.serverStatus();return (s.queues&&s.queues.execution)?s.queues.execution:(s.wiredTiger&&s.wiredTiger.concurrentTransactions)})())'"]}},{"id":"mongo.connection_stats","title":"Incoming connection saturation (serverStatus.connections)","summary":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","description":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Connection counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().connections)'"]}},{"id":"mongo.connections","title":"connPoolStats","summary":"Show connection pool stats — totals, active, available, by host.","description":"Show connection pool stats — totals, active, available, by host.","kind":"exec","risk":"low","side_effects":["One connPoolStats command.","Read-only."],"args":[],"examples":[{"title":"Pool stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({connPoolStats:1}))'"]}},{"id":"mongo.current_op","title":"db.currentOp()","summary":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","description":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[],"examples":[{"title":"Live ops","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true}))'"]}},{"id":"mongo.cursor_stats","title":"Cursor saturation / timed-out cursors (metrics.cursor)","summary":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","description":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cursor counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().metrics.cursor)'"]}},{"id":"mongo.db_list","title":"listDatabases","summary":"List all databases with size + empty flag.","description":"List all databases with size + empty flag.","kind":"exec","risk":"low","side_effects":["One listDatabases command.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({listDatabases:1}))'"]}},{"id":"mongo.db_stats","title":"db.stats()","summary":"Show database-level totals — collections, indexes, data size, storage size.","description":"Show database-level totals — collections, indexes, data size, storage size.","kind":"exec","risk":"low","side_effects":["One dbStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Stats for one DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').stats())\"","emisar","{{ args.database }}"]}},{"id":"mongo.default_rw_concern","title":"Default read/write concern (getDefaultRWConcern)","summary":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","description":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","kind":"exec","risk":"low","side_effects":["One getDefaultRWConcern command.","Read-only."],"args":[],"examples":[{"title":"Default R/W concern","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({getDefaultRWConcern:1}))'"]}},{"id":"mongo.drop_index","title":"db.<coll>.dropIndex(\"<name>\")","summary":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","description":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","kind":"exec","risk":"high","side_effects":["Index removed.","Queries that used the index switch to other indexes or full scan.","Brief lock during the drop."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"index_name","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Drop unused index","args":{"collection":"orders","db_name":"shop","index_name":"user_1_status_1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('${1}').getCollection('${2}').dropIndex('${3}')\"","emisar","{{ args.db_name }}","{{ args.collection }}","{{ args.index_name }}"]}},{"id":"mongo.election_metrics","title":"Election / stepdown history (electionMetrics)","summary":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","description":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Election history","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().electionMetrics)'"]}},{"id":"mongo.explain_query","title":"explain a find()","summary":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","description":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","kind":"exec","risk":"low","side_effects":["One explain command — does NOT execute the query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}},{"name":"filter_json","type":"string","required":false,"default":"{}","description":"JSON filter document.","validation":{"pattern":"^.{0,1000}$"}}],"examples":[{"title":"Plan for {status:'active'}","args":{"collection":"users","database":"production","filter_json":"{\"status\":\"active\"}"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").getCollection(\"'\"$2\"'\").find(JSON.parse(process.env.FILTER || \"{}\")).explain(\"executionStats\"))'","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.get_parameter","title":"getParameter '*'","summary":"List all server parameters (read-only view of the current config).","description":"List all server parameters (read-only view of the current config).","kind":"exec","risk":"low","side_effects":["One getParameter command.","Read-only."],"args":[],"examples":[{"title":"Server parameters","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.adminCommand({getParameter:'*'}))\""]}},{"id":"mongo.global_lock","title":"Global lock queue / active clients (globalLock)","summary":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","description":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Lock queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().globalLock)'"]}},{"id":"mongo.host_info","title":"hostInfo","summary":"Show host CPU, memory, NUMA layout, OS.","description":"Show host CPU, memory, NUMA layout, OS.","kind":"exec","risk":"low","side_effects":["One hostInfo command.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({hostInfo:1}))'"]}},{"id":"mongo.index_builds","title":"In-progress index builds (with progress)","summary":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","description":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","kind":"exec","risk":"low","side_effects":["One $currentOp aggregation on admin.","Read-only."],"args":[],"examples":[{"title":"Active index builds","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"admin\").aggregate([{$currentOp:{idleConnections:true}},{$match:{$or:[{op:\"command\",\"command.createIndexes\":{$exists:true}},{op:\"none\",msg:{$regex:\"^Index Build\"}}]}}]).toArray())'"]}},{"id":"mongo.index_stats","title":"$indexStats aggregation","summary":"Show per-index access counts since server start. Zeros usually mean unused indexes.","description":"Show per-index access counts since server start. Zeros usually mean unused indexes.","kind":"exec","risk":"low","side_effects":["One aggregation.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"Index usage for one coll","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").getCollection(\"'\"$2\"'\").aggregate([{$indexStats:{}}]).toArray())'","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.kill_op","title":"db.killOp(opid)","summary":"Kill one in-flight operation by opid.","description":"Kill one in-flight operation by opid.","kind":"exec","risk":"high","side_effects":["The targeted operation is interrupted.","Connection holding the op may receive an error."],"args":[{"name":"opid","type":"integer","required":true,"description":"Op ID from currentOp.","validation":{"min":1}}],"examples":[{"title":"Kill op 1234","args":{"opid":1234}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.killOp('\"$1\"'))'","emisar","{{ args.opid }}"]}},{"id":"mongo.long_running_ops","title":"Long-running active ops (currentOp, secs_running >= N)","summary":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","description":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[{"name":"min_secs","type":"integer","required":false,"default":5,"description":"Minimum seconds an op must have been running.","validation":{"min":0,"max":86400}}],"examples":[{"title":"Ops running >= 5s","args":{"min_secs":5}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true,secs_running:{$gte:{{ args.min_secs }}}}))'"]}},{"id":"mongo.oplog_size","title":"Oplog size + window","summary":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","description":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('local').runCommand({collStats:'oplog.rs'}))\""]}},{"id":"mongo.profile_slow_queries","title":"Read slow ops from the profiler (system.profile)","summary":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","description":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","kind":"exec","risk":"low","side_effects":["Reads system.profile (a capped collection).","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database whose profiler to read.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"min_millis","type":"integer","required":false,"default":100,"description":"Only ops slower than this many milliseconds.","validation":{"min":0,"max":3600000}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Max documents to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Slowest 20 ops over 100ms","args":{"database":"production","limit":20,"min_millis":100}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").system.profile.find({millis:{$gte:{{ args.min_millis }}}}).sort({ts:-1}).limit({{ args.limit }}).toArray())'","emisar","{{ args.database }}"]}},{"id":"mongo.profiler_status","title":"db.getProfilingStatus()","summary":"Show profiler level + slow-op threshold for one database.","description":"Show profiler level + slow-op threshold for one database.","kind":"exec","risk":"low","side_effects":["One profile command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Profiler level","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getProfilingStatus())\"","emisar","{{ args.database }}"]}},{"id":"mongo.replication_info","title":"Oplog time window (db.getReplicationInfo)","summary":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","description":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog window","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getReplicationInfo())'"]}},{"id":"mongo.replset_config","title":"rs.conf()","summary":"Show replica set configuration — members, votes, priorities, settings.","description":"Show replica set configuration — members, votes, priorities, settings.","kind":"exec","risk":"low","side_effects":["One replSetGetConfig.","Read-only."],"args":[],"examples":[{"title":"RS config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.conf())'"]}},{"id":"mongo.replset_lag","title":"Replication lag (secs behind primary)","summary":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","description":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"Lag for all members","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=rs.status();var p=s.members.filter(function(m){return m.stateStr==\"PRIMARY\"})[0];var pt=p?p.optimeDate:null;return{set:s.set,date:s.date,primary:p?p.name:null,members:s.members.map(function(m){return{name:m.name,stateStr:m.stateStr,health:m.health,optimeDate:m.optimeDate,secsBehindPrimary:(pt&&m.optimeDate)?(pt-m.optimeDate)/1000:null,syncSourceHost:m.syncSourceHost,pingMs:m.pingMs}})}})())'"]}},{"id":"mongo.replset_status","title":"rs.status()","summary":"Show replica set member health, lag, last applied optime.","description":"Show replica set member health, lag, last applied optime.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"RS status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.status())'"]}},{"id":"mongo.replset_stepdown","title":"rs.stepDown(<seconds>)","summary":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","description":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","kind":"exec","risk":"critical","side_effects":["Current primary becomes secondary.","Write unavailability until election finishes.","Connected drivers reconnect to the new primary.","Primary refuses primary status for the specified period."],"args":[{"name":"seconds","type":"integer","required":false,"default":60,"description":"How long the stepped-down node refuses primary.","validation":{"min":5,"max":3600}}],"examples":[{"title":"Step down for 1 minute","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');rs.stepDown({{ args.seconds }})\""]}},{"id":"mongo.server_status","title":"db.serverStatus()","summary":"Show top-level server metrics: connections, ops counters, memory, cluster role.","description":"Show top-level server metrics: connections, ops counters, memory, cluster role.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Full server status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus())'"]}},{"id":"mongo.shard_status","title":"sh.status()","summary":"Show sharded cluster summary — shards, databases, chunk distribution.","description":"Show sharded cluster summary — shards, databases, chunk distribution.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Shard cluster status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");sh.status(true)'"]}},{"id":"mongo.top","title":"db.adminCommand({top:1})","summary":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","description":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","kind":"exec","risk":"low","side_effects":["One top command.","Read-only."],"args":[],"examples":[{"title":"Per-coll time","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({top:1}))'"]}},{"id":"mongo.wiredtiger_cache","title":"WiredTiger cache pressure (serverStatus.wiredTiger.cache)","summary":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","description":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cache stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().wiredTiger.cache)'"]}}],"previous_versions":[{"version":"0.3.5","content_hash":"sha256:f8f1081f60d43099c1c61e943f14ff70e9c4d6ecadfe2d459cf32a5e2fddc58f","tarball_url":"https://registry.emisar.dev/v1/packs/mongodb/0.3.5/f8f1081f60d43099c1c61e943f14ff70e9c4d6ecadfe2d459cf32a5e2fddc58f/pack.tar.gz","actions":[{"id":"mongo.balancer_status","title":"sh.getBalancerState()","summary":"Show whether the balancer is enabled + currently running.","description":"Show whether the balancer is enabled + currently running.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Balancer state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify({enabled:sh.getBalancerState(),running:sh.isBalancerRunning()})'"]}},{"id":"mongo.build_info","title":"buildInfo","summary":"Show server version + build flags.","description":"Show server version + build flags.","kind":"exec","risk":"low","side_effects":["One buildInfo command.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({buildInfo:1}))'"]}},{"id":"mongo.collection_list","title":"db.getCollectionNames()","summary":"List collections in one database.","description":"List collections in one database.","kind":"exec","risk":"low","side_effects":["One listCollections command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Collections in DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getCollectionNames())\"","emisar","{{ args.database }}"]}},{"id":"mongo.collection_stats","title":"db.<coll>.stats()","summary":"Show per-collection totals — count, size, storage, indexes.","description":"Show per-collection totals — count, size, storage, indexes.","kind":"exec","risk":"low","side_effects":["One collStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"One collection","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getCollection('${2}').stats())\"","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.compact_collection","title":"db.runCommand({compact:\"<coll>\"})","summary":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","description":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","kind":"exec","risk":"high","side_effects":["Collection's reads/writes blocked until compaction finishes.","Disk usage drops.","Other collections unaffected."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Compact after a large delete","args":{"collection":"events","db_name":"analytics"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('${1}').runCommand({compact: '${2}'})\"","emisar","{{ args.db_name }}","{{ args.collection }}"]}},{"id":"mongo.concurrent_transactions","title":"Read/write tickets (concurrency saturation)","summary":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","description":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Ticket pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=db.serverStatus();return (s.queues&&s.queues.execution)?s.queues.execution:(s.wiredTiger&&s.wiredTiger.concurrentTransactions)})())'"]}},{"id":"mongo.connection_stats","title":"Incoming connection saturation (serverStatus.connections)","summary":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","description":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Connection counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().connections)'"]}},{"id":"mongo.connections","title":"connPoolStats","summary":"Show connection pool stats — totals, active, available, by host.","description":"Show connection pool stats — totals, active, available, by host.","kind":"exec","risk":"low","side_effects":["One connPoolStats command.","Read-only."],"args":[],"examples":[{"title":"Pool stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({connPoolStats:1}))'"]}},{"id":"mongo.current_op","title":"db.currentOp()","summary":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","description":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[],"examples":[{"title":"Live ops","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true}))'"]}},{"id":"mongo.cursor_stats","title":"Cursor saturation / timed-out cursors (metrics.cursor)","summary":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","description":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cursor counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().metrics.cursor)'"]}},{"id":"mongo.db_list","title":"listDatabases","summary":"List all databases with size + empty flag.","description":"List all databases with size + empty flag.","kind":"exec","risk":"low","side_effects":["One listDatabases command.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({listDatabases:1}))'"]}},{"id":"mongo.db_stats","title":"db.stats()","summary":"Show database-level totals — collections, indexes, data size, storage size.","description":"Show database-level totals — collections, indexes, data size, storage size.","kind":"exec","risk":"low","side_effects":["One dbStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Stats for one DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').stats())\"","emisar","{{ args.database }}"]}},{"id":"mongo.default_rw_concern","title":"Default read/write concern (getDefaultRWConcern)","summary":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","description":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","kind":"exec","risk":"low","side_effects":["One getDefaultRWConcern command.","Read-only."],"args":[],"examples":[{"title":"Default R/W concern","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({getDefaultRWConcern:1}))'"]}},{"id":"mongo.drop_index","title":"db.<coll>.dropIndex(\"<name>\")","summary":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","description":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","kind":"exec","risk":"high","side_effects":["Index removed.","Queries that used the index switch to other indexes or full scan.","Brief lock during the drop."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"index_name","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Drop unused index","args":{"collection":"orders","db_name":"shop","index_name":"user_1_status_1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('${1}').getCollection('${2}').dropIndex('${3}')\"","emisar","{{ args.db_name }}","{{ args.collection }}","{{ args.index_name }}"]}},{"id":"mongo.election_metrics","title":"Election / stepdown history (electionMetrics)","summary":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","description":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Election history","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().electionMetrics)'"]}},{"id":"mongo.explain_query","title":"explain a find()","summary":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","description":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","kind":"exec","risk":"low","side_effects":["One explain command — does NOT execute the query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}},{"name":"filter_json","type":"string","required":false,"default":"{}","description":"JSON filter document.","validation":{"pattern":"^.{0,1000}$"}}],"examples":[{"title":"Plan for {status:'active'}","args":{"collection":"users","database":"production","filter_json":"{\"status\":\"active\"}"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").getCollection(\"'\"$2\"'\").find(JSON.parse(process.env.FILTER || \"{}\")).explain(\"executionStats\"))'","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.get_parameter","title":"getParameter '*'","summary":"List all server parameters (read-only view of the current config).","description":"List all server parameters (read-only view of the current config).","kind":"exec","risk":"low","side_effects":["One getParameter command.","Read-only."],"args":[],"examples":[{"title":"Server parameters","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.adminCommand({getParameter:'*'}))\""]}},{"id":"mongo.global_lock","title":"Global lock queue / active clients (globalLock)","summary":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","description":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Lock queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().globalLock)'"]}},{"id":"mongo.host_info","title":"hostInfo","summary":"Show host CPU, memory, NUMA layout, OS.","description":"Show host CPU, memory, NUMA layout, OS.","kind":"exec","risk":"low","side_effects":["One hostInfo command.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({hostInfo:1}))'"]}},{"id":"mongo.index_builds","title":"In-progress index builds (with progress)","summary":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","description":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","kind":"exec","risk":"low","side_effects":["One $currentOp aggregation on admin.","Read-only."],"args":[],"examples":[{"title":"Active index builds","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"admin\").aggregate([{$currentOp:{idleConnections:true}},{$match:{$or:[{op:\"command\",\"command.createIndexes\":{$exists:true}},{op:\"none\",msg:{$regex:\"^Index Build\"}}]}}]).toArray())'"]}},{"id":"mongo.index_stats","title":"$indexStats aggregation","summary":"Show per-index access counts since server start. Zeros usually mean unused indexes.","description":"Show per-index access counts since server start. Zeros usually mean unused indexes.","kind":"exec","risk":"low","side_effects":["One aggregation.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"Index usage for one coll","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").getCollection(\"'\"$2\"'\").aggregate([{$indexStats:{}}]).toArray())'","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.kill_op","title":"db.killOp(opid)","summary":"Kill one in-flight operation by opid.","description":"Kill one in-flight operation by opid.","kind":"exec","risk":"high","side_effects":["The targeted operation is interrupted.","Connection holding the op may receive an error."],"args":[{"name":"opid","type":"integer","required":true,"description":"Op ID from currentOp.","validation":{"min":1}}],"examples":[{"title":"Kill op 1234","args":{"opid":1234}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.killOp('\"$1\"'))'","emisar","{{ args.opid }}"]}},{"id":"mongo.long_running_ops","title":"Long-running active ops (currentOp, secs_running >= N)","summary":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","description":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[{"name":"min_secs","type":"integer","required":false,"default":5,"description":"Minimum seconds an op must have been running.","validation":{"min":0,"max":86400}}],"examples":[{"title":"Ops running >= 5s","args":{"min_secs":5}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true,secs_running:{$gte:{{ args.min_secs }}}}))'"]}},{"id":"mongo.oplog_size","title":"Oplog size + window","summary":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","description":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('local').runCommand({collStats:'oplog.rs'}))\""]}},{"id":"mongo.profile_slow_queries","title":"Read slow ops from the profiler (system.profile)","summary":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","description":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","kind":"exec","risk":"low","side_effects":["Reads system.profile (a capped collection).","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database whose profiler to read.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"min_millis","type":"integer","required":false,"default":100,"description":"Only ops slower than this many milliseconds.","validation":{"min":0,"max":3600000}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Max documents to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Slowest 20 ops over 100ms","args":{"database":"production","limit":20,"min_millis":100}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").system.profile.find({millis:{$gte:{{ args.min_millis }}}}).sort({ts:-1}).limit({{ args.limit }}).toArray())'","emisar","{{ args.database }}"]}},{"id":"mongo.profiler_status","title":"db.getProfilingStatus()","summary":"Show profiler level + slow-op threshold for one database.","description":"Show profiler level + slow-op threshold for one database.","kind":"exec","risk":"low","side_effects":["One profile command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Profiler level","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getProfilingStatus())\"","emisar","{{ args.database }}"]}},{"id":"mongo.replication_info","title":"Oplog time window (db.getReplicationInfo)","summary":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","description":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog window","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getReplicationInfo())'"]}},{"id":"mongo.replset_config","title":"rs.conf()","summary":"Show replica set configuration — members, votes, priorities, settings.","description":"Show replica set configuration — members, votes, priorities, settings.","kind":"exec","risk":"low","side_effects":["One replSetGetConfig.","Read-only."],"args":[],"examples":[{"title":"RS config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.conf())'"]}},{"id":"mongo.replset_lag","title":"Replication lag (secs behind primary)","summary":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","description":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"Lag for all members","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=rs.status();var p=s.members.filter(function(m){return m.stateStr==\"PRIMARY\"})[0];var pt=p?p.optimeDate:null;return{set:s.set,date:s.date,primary:p?p.name:null,members:s.members.map(function(m){return{name:m.name,stateStr:m.stateStr,health:m.health,optimeDate:m.optimeDate,secsBehindPrimary:(pt&&m.optimeDate)?(pt-m.optimeDate)/1000:null,syncSourceHost:m.syncSourceHost,pingMs:m.pingMs}})}})())'"]}},{"id":"mongo.replset_status","title":"rs.status()","summary":"Show replica set member health, lag, last applied optime.","description":"Show replica set member health, lag, last applied optime.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"RS status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.status())'"]}},{"id":"mongo.replset_stepdown","title":"rs.stepDown(<seconds>)","summary":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","description":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","kind":"exec","risk":"critical","side_effects":["Current primary becomes secondary.","Write unavailability until election finishes.","Connected drivers reconnect to the new primary.","Primary refuses primary status for the specified period."],"args":[{"name":"seconds","type":"integer","required":false,"default":60,"description":"How long the stepped-down node refuses primary.","validation":{"min":5,"max":3600}}],"examples":[{"title":"Step down for 1 minute","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');rs.stepDown({{ args.seconds }})\""]}},{"id":"mongo.server_status","title":"db.serverStatus()","summary":"Show top-level server metrics: connections, ops counters, memory, cluster role.","description":"Show top-level server metrics: connections, ops counters, memory, cluster role.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Full server status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus())'"]}},{"id":"mongo.shard_status","title":"sh.status()","summary":"Show sharded cluster summary — shards, databases, chunk distribution.","description":"Show sharded cluster summary — shards, databases, chunk distribution.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Shard cluster status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");sh.status(true)'"]}},{"id":"mongo.top","title":"db.adminCommand({top:1})","summary":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","description":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","kind":"exec","risk":"low","side_effects":["One top command.","Read-only."],"args":[],"examples":[{"title":"Per-coll time","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({top:1}))'"]}},{"id":"mongo.wiredtiger_cache","title":"WiredTiger cache pressure (serverStatus.wiredTiger.cache)","summary":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","description":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cache stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().wiredTiger.cache)'"]}}]},{"version":"0.3.4","content_hash":"sha256:7c737c709bc7d854c94f7152307a55d64bda5dca033cca12ce4caa70dcf2c097","tarball_url":"https://registry.emisar.dev/v1/packs/mongodb/0.3.4/7c737c709bc7d854c94f7152307a55d64bda5dca033cca12ce4caa70dcf2c097/pack.tar.gz","actions":[{"id":"mongo.balancer_status","title":"sh.getBalancerState()","summary":"Show whether the balancer is enabled + currently running.","description":"Show whether the balancer is enabled + currently running.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Balancer state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify({enabled:sh.getBalancerState(),running:sh.isBalancerRunning()})'"]}},{"id":"mongo.build_info","title":"buildInfo","summary":"Show server version + build flags.","description":"Show server version + build flags.","kind":"exec","risk":"low","side_effects":["One buildInfo command.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({buildInfo:1}))'"]}},{"id":"mongo.collection_list","title":"db.getCollectionNames()","summary":"List collections in one database.","description":"List collections in one database.","kind":"exec","risk":"low","side_effects":["One listCollections command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Collections in DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getCollectionNames())\"","emisar","{{ args.database }}"]}},{"id":"mongo.collection_stats","title":"db.<coll>.stats()","summary":"Show per-collection totals — count, size, storage, indexes.","description":"Show per-collection totals — count, size, storage, indexes.","kind":"exec","risk":"low","side_effects":["One collStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"One collection","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getCollection('${2}').stats())\"","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.compact_collection","title":"db.runCommand({compact:\"<coll>\"})","summary":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","description":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","kind":"exec","risk":"high","side_effects":["Collection's reads/writes blocked until compaction finishes.","Disk usage drops.","Other collections unaffected."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Compact after a large delete","args":{"collection":"events","db_name":"analytics"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('${1}').runCommand({compact: '${2}'})\"","emisar","{{ args.db_name }}","{{ args.collection }}"]}},{"id":"mongo.concurrent_transactions","title":"Read/write tickets (concurrency saturation)","summary":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","description":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Ticket pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=db.serverStatus();return (s.queues&&s.queues.execution)?s.queues.execution:(s.wiredTiger&&s.wiredTiger.concurrentTransactions)})())'"]}},{"id":"mongo.connection_stats","title":"Incoming connection saturation (serverStatus.connections)","summary":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","description":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Connection counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().connections)'"]}},{"id":"mongo.connections","title":"connPoolStats","summary":"Show connection pool stats — totals, active, available, by host.","description":"Show connection pool stats — totals, active, available, by host.","kind":"exec","risk":"low","side_effects":["One connPoolStats command.","Read-only."],"args":[],"examples":[{"title":"Pool stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({connPoolStats:1}))'"]}},{"id":"mongo.current_op","title":"db.currentOp()","summary":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","description":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[],"examples":[{"title":"Live ops","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true}))'"]}},{"id":"mongo.cursor_stats","title":"Cursor saturation / timed-out cursors (metrics.cursor)","summary":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","description":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cursor counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().metrics.cursor)'"]}},{"id":"mongo.db_list","title":"listDatabases","summary":"List all databases with size + empty flag.","description":"List all databases with size + empty flag.","kind":"exec","risk":"low","side_effects":["One listDatabases command.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({listDatabases:1}))'"]}},{"id":"mongo.db_stats","title":"db.stats()","summary":"Show database-level totals — collections, indexes, data size, storage size.","description":"Show database-level totals — collections, indexes, data size, storage size.","kind":"exec","risk":"low","side_effects":["One dbStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Stats for one DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').stats())\"","emisar","{{ args.database }}"]}},{"id":"mongo.default_rw_concern","title":"Default read/write concern (getDefaultRWConcern)","summary":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","description":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","kind":"exec","risk":"low","side_effects":["One getDefaultRWConcern command.","Read-only."],"args":[],"examples":[{"title":"Default R/W concern","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({getDefaultRWConcern:1}))'"]}},{"id":"mongo.drop_index","title":"db.<coll>.dropIndex(\"<name>\")","summary":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","description":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","kind":"exec","risk":"high","side_effects":["Index removed.","Queries that used the index switch to other indexes or full scan.","Brief lock during the drop."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"index_name","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Drop unused index","args":{"collection":"orders","db_name":"shop","index_name":"user_1_status_1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('${1}').getCollection('${2}').dropIndex('${3}')\"","emisar","{{ args.db_name }}","{{ args.collection }}","{{ args.index_name }}"]}},{"id":"mongo.election_metrics","title":"Election / stepdown history (electionMetrics)","summary":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","description":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Election history","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().electionMetrics)'"]}},{"id":"mongo.explain_query","title":"explain a find()","summary":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","description":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","kind":"exec","risk":"low","side_effects":["One explain command — does NOT execute the query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}},{"name":"filter_json","type":"string","required":false,"default":"{}","description":"JSON filter document.","validation":{"pattern":"^.{0,1000}$"}}],"examples":[{"title":"Plan for {status:'active'}","args":{"collection":"users","database":"production","filter_json":"{\"status\":\"active\"}"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").getCollection(\"'\"$2\"'\").find(JSON.parse(process.env.FILTER || \"{}\")).explain(\"executionStats\"))'","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.get_parameter","title":"getParameter '*'","summary":"List all server parameters (read-only view of the current config).","description":"List all server parameters (read-only view of the current config).","kind":"exec","risk":"low","side_effects":["One getParameter command.","Read-only."],"args":[],"examples":[{"title":"Server parameters","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.adminCommand({getParameter:'*'}))\""]}},{"id":"mongo.global_lock","title":"Global lock queue / active clients (globalLock)","summary":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","description":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Lock queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().globalLock)'"]}},{"id":"mongo.host_info","title":"hostInfo","summary":"Show host CPU, memory, NUMA layout, OS.","description":"Show host CPU, memory, NUMA layout, OS.","kind":"exec","risk":"low","side_effects":["One hostInfo command.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({hostInfo:1}))'"]}},{"id":"mongo.index_builds","title":"In-progress index builds (with progress)","summary":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","description":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","kind":"exec","risk":"low","side_effects":["One $currentOp aggregation on admin.","Read-only."],"args":[],"examples":[{"title":"Active index builds","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"admin\").aggregate([{$currentOp:{idleConnections:true}},{$match:{$or:[{op:\"command\",\"command.createIndexes\":{$exists:true}},{op:\"none\",msg:{$regex:\"^Index Build\"}}]}}]).toArray())'"]}},{"id":"mongo.index_stats","title":"$indexStats aggregation","summary":"Show per-index access counts since server start. Zeros usually mean unused indexes.","description":"Show per-index access counts since server start. Zeros usually mean unused indexes.","kind":"exec","risk":"low","side_effects":["One aggregation.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"Index usage for one coll","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").getCollection(\"'\"$2\"'\").aggregate([{$indexStats:{}}]).toArray())'","emisar","{{ args.database }}","{{ args.collection }}"]}},{"id":"mongo.kill_op","title":"db.killOp(opid)","summary":"Kills one in-flight operation by opid.","description":"Kills one in-flight operation by opid.","kind":"exec","risk":"high","side_effects":["The targeted operation is interrupted.","Connection holding the op may receive an error."],"args":[{"name":"opid","type":"integer","required":true,"description":"Op ID from currentOp.","validation":{"min":1}}],"examples":[{"title":"Kill op 1234","args":{"opid":1234}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.killOp('\"$1\"'))'","emisar","{{ args.opid }}"]}},{"id":"mongo.long_running_ops","title":"Long-running active ops (currentOp, secs_running >= N)","summary":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","description":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[{"name":"min_secs","type":"integer","required":false,"default":5,"description":"Minimum seconds an op must have been running.","validation":{"min":0,"max":86400}}],"examples":[{"title":"Ops running >= 5s","args":{"min_secs":5}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true,secs_running:{$gte:{{ args.min_secs }}}}))'"]}},{"id":"mongo.oplog_size","title":"Oplog size + window","summary":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","description":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('local').runCommand({collStats:'oplog.rs'}))\""]}},{"id":"mongo.profile_slow_queries","title":"Read slow ops from the profiler (system.profile)","summary":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","description":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","kind":"exec","risk":"low","side_effects":["Reads system.profile (a capped collection).","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database whose profiler to read.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"min_millis","type":"integer","required":false,"default":100,"description":"Only ops slower than this many milliseconds.","validation":{"min":0,"max":3600000}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Max documents to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Slowest 20 ops over 100ms","args":{"database":"production","limit":20,"min_millis":100}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"'\"$1\"'\").system.profile.find({millis:{$gte:{{ args.min_millis }}}}).sort({ts:-1}).limit({{ args.limit }}).toArray())'","emisar","{{ args.database }}"]}},{"id":"mongo.profiler_status","title":"db.getProfilingStatus()","summary":"Show profiler level + slow-op threshold for one database.","description":"Show profiler level + slow-op threshold for one database.","kind":"exec","risk":"low","side_effects":["One profile command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Profiler level","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('${1}').getProfilingStatus())\"","emisar","{{ args.database }}"]}},{"id":"mongo.replication_info","title":"Oplog time window (db.getReplicationInfo)","summary":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","description":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog window","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getReplicationInfo())'"]}},{"id":"mongo.replset_config","title":"rs.conf()","summary":"Show replica set configuration — members, votes, priorities, settings.","description":"Show replica set configuration — members, votes, priorities, settings.","kind":"exec","risk":"low","side_effects":["One replSetGetConfig.","Read-only."],"args":[],"examples":[{"title":"RS config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.conf())'"]}},{"id":"mongo.replset_lag","title":"Replication lag (secs behind primary)","summary":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","description":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"Lag for all members","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=rs.status();var p=s.members.filter(function(m){return m.stateStr==\"PRIMARY\"})[0];var pt=p?p.optimeDate:null;return{set:s.set,date:s.date,primary:p?p.name:null,members:s.members.map(function(m){return{name:m.name,stateStr:m.stateStr,health:m.health,optimeDate:m.optimeDate,secsBehindPrimary:(pt&&m.optimeDate)?(pt-m.optimeDate)/1000:null,syncSourceHost:m.syncSourceHost,pingMs:m.pingMs}})}})())'"]}},{"id":"mongo.replset_status","title":"rs.status()","summary":"Show replica set member health, lag, last applied optime.","description":"Show replica set member health, lag, last applied optime.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"RS status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.status())'"]}},{"id":"mongo.replset_stepdown","title":"rs.stepDown(<seconds>)","summary":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","description":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","kind":"exec","risk":"critical","side_effects":["Current primary becomes secondary.","Write unavailability until election finishes.","Connected drivers reconnect to the new primary.","Primary refuses primary status for the specified period."],"args":[{"name":"seconds","type":"integer","required":false,"default":60,"description":"How long the stepped-down node refuses primary.","validation":{"min":5,"max":3600}}],"examples":[{"title":"Step down for 1 minute","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');rs.stepDown({{ args.seconds }})\""]}},{"id":"mongo.server_status","title":"db.serverStatus()","summary":"Show top-level server metrics: connections, ops counters, memory, cluster role.","description":"Show top-level server metrics: connections, ops counters, memory, cluster role.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Full server status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus())'"]}},{"id":"mongo.shard_status","title":"sh.status()","summary":"Show sharded cluster summary — shards, databases, chunk distribution.","description":"Show sharded cluster summary — shards, databases, chunk distribution.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Shard cluster status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");sh.status(true)'"]}},{"id":"mongo.top","title":"db.adminCommand({top:1})","summary":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","description":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","kind":"exec","risk":"low","side_effects":["One top command.","Read-only."],"args":[],"examples":[{"title":"Per-coll time","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({top:1}))'"]}},{"id":"mongo.wiredtiger_cache","title":"WiredTiger cache pressure (serverStatus.wiredTiger.cache)","summary":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","description":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cache stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().wiredTiger.cache)'"]}}]},{"version":"0.3.3","content_hash":"sha256:6cb6f6f071ff95b5811585527078f26aed6dd2fb6c2f31a5de94e6e33af64bae","tarball_url":"https://registry.emisar.dev/v1/packs/mongodb/0.3.3/6cb6f6f071ff95b5811585527078f26aed6dd2fb6c2f31a5de94e6e33af64bae/pack.tar.gz","actions":[{"id":"mongo.balancer_status","title":"sh.getBalancerState()","summary":"Show whether the balancer is enabled + currently running.","description":"Show whether the balancer is enabled + currently running.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Balancer state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify({enabled:sh.getBalancerState(),running:sh.isBalancerRunning()})'"]}},{"id":"mongo.build_info","title":"buildInfo","summary":"Show server version + build flags.","description":"Show server version + build flags.","kind":"exec","risk":"low","side_effects":["One buildInfo command.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({buildInfo:1}))'"]}},{"id":"mongo.collection_list","title":"db.getCollectionNames()","summary":"List collections in one database.","description":"List collections in one database.","kind":"exec","risk":"low","side_effects":["One listCollections command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Collections in DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('{{ args.database }}').getCollectionNames())\""]}},{"id":"mongo.collection_stats","title":"db.<coll>.stats()","summary":"Show per-collection totals — count, size, storage, indexes.","description":"Show per-collection totals — count, size, storage, indexes.","kind":"exec","risk":"low","side_effects":["One collStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"One collection","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('{{ args.database }}').getCollection('{{ args.collection }}').stats())\""]}},{"id":"mongo.compact_collection","title":"db.runCommand({compact:\"<coll>\"})","summary":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","description":"Compact one collection on the connected node. Reclaims disk for WiredTiger after large deletes. BLOCKS reads/writes on the collection during compaction. Run during a low-traffic window; prefer running on a secondary first.","kind":"exec","risk":"high","side_effects":["Collection's reads/writes blocked until compaction finishes.","Disk usage drops.","Other collections unaffected."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Compact after a large delete","args":{"collection":"events","db_name":"analytics"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('{{ args.db_name }}').runCommand({compact: '{{ args.collection }}'})\""]}},{"id":"mongo.concurrent_transactions","title":"Read/write tickets (concurrency saturation)","summary":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","description":"Show read/write ticket pools — out vs available. Queued/exhausted tickets are the classic sign of storage-engine overload. Version-tolerant: reads queues.execution on MongoDB 8.0+, else wiredTiger.concurrentTransactions (<= 7.0).","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Ticket pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=db.serverStatus();return (s.queues&&s.queues.execution)?s.queues.execution:(s.wiredTiger&&s.wiredTiger.concurrentTransactions)})())'"]}},{"id":"mongo.connection_stats","title":"Incoming connection saturation (serverStatus.connections)","summary":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","description":"Show incoming connection counts — current, available, active, totalCreated. Approaching the available limit means new clients will be refused. Distinct from connections (connPoolStats), which is the outgoing pool.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Connection counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().connections)'"]}},{"id":"mongo.connections","title":"connPoolStats","summary":"Show connection pool stats — totals, active, available, by host.","description":"Show connection pool stats — totals, active, available, by host.","kind":"exec","risk":"low","side_effects":["One connPoolStats command.","Read-only."],"args":[],"examples":[{"title":"Pool stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({connPoolStats:1}))'"]}},{"id":"mongo.current_op","title":"db.currentOp()","summary":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","description":"List in-flight operations. The canonical \"what is the server doing right now?\" check.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[],"examples":[{"title":"Live ops","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true}))'"]}},{"id":"mongo.cursor_stats","title":"Cursor saturation / timed-out cursors (metrics.cursor)","summary":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","description":"Show cursor counts — open.total, open.noTimeout, open.pinned, timedOut, totalOpened. A growing timedOut count usually means an application is leaking cursors.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cursor counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().metrics.cursor)'"]}},{"id":"mongo.db_list","title":"listDatabases","summary":"List all databases with size + empty flag.","description":"List all databases with size + empty flag.","kind":"exec","risk":"low","side_effects":["One listDatabases command.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({listDatabases:1}))'"]}},{"id":"mongo.db_stats","title":"db.stats()","summary":"Show database-level totals — collections, indexes, data size, storage size.","description":"Show database-level totals — collections, indexes, data size, storage size.","kind":"exec","risk":"low","side_effects":["One dbStats command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Stats for one DB","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('{{ args.database }}').stats())\""]}},{"id":"mongo.default_rw_concern","title":"Default read/write concern (getDefaultRWConcern)","summary":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","description":"Show cluster default read and write concern (e.g. w:majority) and its source. The durability/consistency config for the replica set — a weakened default write concern is a common cause of surprising data loss on failover.","kind":"exec","risk":"low","side_effects":["One getDefaultRWConcern command.","Read-only."],"args":[],"examples":[{"title":"Default R/W concern","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({getDefaultRWConcern:1}))'"]}},{"id":"mongo.drop_index","title":"db.<coll>.dropIndex(\"<name>\")","summary":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","description":"Drop one index from a collection. Use to remove a hot or unused index discovered via index_stats. Queries that relied on the index degrade to COLLSCAN until rebuilt or replaced.","kind":"exec","risk":"high","side_effects":["Index removed.","Queries that used the index switch to other indexes or full scan.","Brief lock during the drop."],"args":[{"name":"db_name","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}},{"name":"index_name","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,128}$"}}],"examples":[{"title":"Drop unused index","args":{"collection":"orders","db_name":"shop","index_name":"user_1_status_1"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');db.getSiblingDB('{{ args.db_name }}').getCollection('{{ args.collection }}').dropIndex('{{ args.index_name }}')\""]}},{"id":"mongo.election_metrics","title":"Election / stepdown history (electionMetrics)","summary":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","description":"Show cumulative election and stepdown counters for this member — stepUpCmd, priorityTakeover, electionTimeout, catchUpTakeover, numStepDownsCausedBy HigherTerm, numCatchUps. Use to see how often the set has been re-electing.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Election history","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().electionMetrics)'"]}},{"id":"mongo.explain_query","title":"explain a find()","summary":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","description":"Show the execution plan for `find(filter)` on one collection at `executionStats` verbosity.","kind":"exec","risk":"low","side_effects":["One explain command — does NOT execute the query.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}},{"name":"filter_json","type":"string","required":false,"default":"{}","description":"JSON filter document.","validation":{"pattern":"^.{0,1000}$"}}],"examples":[{"title":"Plan for {status:'active'}","args":{"collection":"users","database":"production","filter_json":"{\"status\":\"active\"}"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"{{ args.database }}\").getCollection(\"{{ args.collection }}\").find(JSON.parse(process.env.FILTER || \"{}\")).explain(\"executionStats\"))'"]}},{"id":"mongo.get_parameter","title":"getParameter '*'","summary":"List all server parameters (read-only view of the current config).","description":"List all server parameters (read-only view of the current config).","kind":"exec","risk":"low","side_effects":["One getParameter command.","Read-only."],"args":[],"examples":[{"title":"Server parameters","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.adminCommand({getParameter:'*'}))\""]}},{"id":"mongo.global_lock","title":"Global lock queue / active clients (globalLock)","summary":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","description":"Show global lock contention — currentQueue (total/readers/writers) waiting on the lock, and activeClients (total/readers/writers). A growing queue points to lock contention or an overloaded server.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Lock queue","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().globalLock)'"]}},{"id":"mongo.host_info","title":"hostInfo","summary":"Show host CPU, memory, NUMA layout, OS.","description":"Show host CPU, memory, NUMA layout, OS.","kind":"exec","risk":"low","side_effects":["One hostInfo command.","Read-only."],"args":[],"examples":[{"title":"Host info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({hostInfo:1}))'"]}},{"id":"mongo.index_builds","title":"In-progress index builds (with progress)","summary":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","description":"List active index-build operations with progress (done/total), via $currentOp. The canonical \"is an index build stuck / how far along is it\" check across the deployment.","kind":"exec","risk":"low","side_effects":["One $currentOp aggregation on admin.","Read-only."],"args":[],"examples":[{"title":"Active index builds","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"admin\").aggregate([{$currentOp:{idleConnections:true}},{$match:{$or:[{op:\"command\",\"command.createIndexes\":{$exists:true}},{op:\"none\",msg:{$regex:\"^Index Build\"}}]}}]).toArray())'"]}},{"id":"mongo.index_stats","title":"$indexStats aggregation","summary":"Show per-index access counts since server start. Zeros usually mean unused indexes.","description":"Show per-index access counts since server start. Zeros usually mean unused indexes.","kind":"exec","risk":"low","side_effects":["One aggregation.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"collection","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,120}$"}}],"examples":[{"title":"Index usage for one coll","args":{"collection":"users","database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"{{ args.database }}\").getCollection(\"{{ args.collection }}\").aggregate([{$indexStats:{}}]).toArray())'"]}},{"id":"mongo.kill_op","title":"db.killOp(opid)","summary":"Kills one in-flight operation by opid.","description":"Kills one in-flight operation by opid.","kind":"exec","risk":"high","side_effects":["The targeted operation is interrupted.","Connection holding the op may receive an error."],"args":[{"name":"opid","type":"integer","required":true,"description":"Op ID from currentOp.","validation":{"min":1}}],"examples":[{"title":"Kill op 1234","args":{"opid":1234}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.killOp({{ args.opid }}))'"]}},{"id":"mongo.long_running_ops","title":"Long-running active ops (currentOp, secs_running >= N)","summary":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","description":"List active operations that have been running at least N seconds — the canonical hunt for a hung or blocked op. Filters currentOp by secs_running.","kind":"exec","risk":"low","side_effects":["One currentOp command.","Read-only."],"args":[{"name":"min_secs","type":"integer","required":false,"default":5,"description":"Minimum seconds an op must have been running.","validation":{"min":0,"max":86400}}],"examples":[{"title":"Ops running >= 5s","args":{"min_secs":5}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.currentOp({active:true,secs_running:{$gte:{{ args.min_secs }}}}))'"]}},{"id":"mongo.oplog_size","title":"Oplog size + window","summary":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","description":"Show oplog size + first/last timestamps + estimated time window. The canonical \"how far can a secondary fall behind?\" check.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('local').runCommand({collStats:'oplog.rs'}))\""]}},{"id":"mongo.profile_slow_queries","title":"Read slow ops from the profiler (system.profile)","summary":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","description":"Read the database profiler collection (system.profile) for the slowest recent ops over a millis threshold, newest first. Requires profiling to be enabled on the database already (see profiler_status); does not change it.","kind":"exec","risk":"low","side_effects":["Reads system.profile (a capped collection).","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database whose profiler to read.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}},{"name":"min_millis","type":"integer","required":false,"default":100,"description":"Only ops slower than this many milliseconds.","validation":{"min":0,"max":3600000}},{"name":"limit","type":"integer","required":false,"default":20,"description":"Max documents to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Slowest 20 ops over 100ms","args":{"database":"production","limit":20,"min_millis":100}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getSiblingDB(\"{{ args.database }}\").system.profile.find({millis:{$gte:{{ args.min_millis }}}}).sort({ts:-1}).limit({{ args.limit }}).toArray())'"]}},{"id":"mongo.profiler_status","title":"db.getProfilingStatus()","summary":"Show profiler level + slow-op threshold for one database.","description":"Show profiler level + slow-op threshold for one database.","kind":"exec","risk":"low","side_effects":["One profile command.","Read-only."],"args":[{"name":"database","type":"string","required":true,"description":"Database name.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,63}$"}}],"examples":[{"title":"Profiler level","args":{"database":"production"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' \"db=new Mongo(process.env.MONGO_URI).getDB('admin');JSON.stringify(db.getSiblingDB('{{ args.database }}').getProfilingStatus())\""]}},{"id":"mongo.replication_info","title":"Oplog time window (db.getReplicationInfo)","summary":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","description":"Show oplog time window — logSizeMB, usedMB, timeDiff / timeDiffHours, tFirst, tLast. How much history the oplog retains, which bounds how long a secondary can be down before it needs a full resync. Distinct from oplog size.","kind":"exec","risk":"low","side_effects":["Reads oplog metadata.","Read-only."],"args":[],"examples":[{"title":"Oplog window","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.getReplicationInfo())'"]}},{"id":"mongo.replset_config","title":"rs.conf()","summary":"Show replica set configuration — members, votes, priorities, settings.","description":"Show replica set configuration — members, votes, priorities, settings.","kind":"exec","risk":"low","side_effects":["One replSetGetConfig.","Read-only."],"args":[],"examples":[{"title":"RS config","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.conf())'"]}},{"id":"mongo.replset_lag","title":"Replication lag (secs behind primary)","summary":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","description":"Show per-member seconds behind the primary, computed from rs.status() optimeDate (with state, health, sync source, ping). The canonical replica-set lag check.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"Lag for all members","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify((function(){var s=rs.status();var p=s.members.filter(function(m){return m.stateStr==\"PRIMARY\"})[0];var pt=p?p.optimeDate:null;return{set:s.set,date:s.date,primary:p?p.name:null,members:s.members.map(function(m){return{name:m.name,stateStr:m.stateStr,health:m.health,optimeDate:m.optimeDate,secsBehindPrimary:(pt&&m.optimeDate)?(pt-m.optimeDate)/1000:null,syncSourceHost:m.syncSourceHost,pingMs:m.pingMs}})}})())'"]}},{"id":"mongo.replset_status","title":"rs.status()","summary":"Show replica set member health, lag, last applied optime.","description":"Show replica set member health, lag, last applied optime.","kind":"exec","risk":"low","side_effects":["One replSetGetStatus.","Read-only."],"args":[],"examples":[{"title":"RS status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(rs.status())'"]}},{"id":"mongo.replset_stepdown","title":"rs.stepDown(<seconds>)","summary":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","description":"Force the current primary to step down. Replica set elects a new primary; ~5–15s of write unavailability is typical. Use during planned failover when one secondary is known healthier.","kind":"exec","risk":"critical","side_effects":["Current primary becomes secondary.","Write unavailability until election finishes.","Connected drivers reconnect to the new primary.","Primary refuses primary status for the specified period."],"args":[{"name":"seconds","type":"integer","required":false,"default":60,"description":"How long the stepped-down node refuses primary.","validation":{"min":5,"max":3600}}],"examples":[{"title":"Step down for 1 minute","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh --nodb --quiet --eval \"db=new Mongo(process.env.MONGO_URI).getDB('admin');rs.stepDown({{ args.seconds }})\""]}},{"id":"mongo.server_status","title":"db.serverStatus()","summary":"Show top-level server metrics: connections, ops counters, memory, cluster role.","description":"Show top-level server metrics: connections, ops counters, memory, cluster role.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Full server status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus())'"]}},{"id":"mongo.shard_status","title":"sh.status()","summary":"Show sharded cluster summary — shards, databases, chunk distribution.","description":"Show sharded cluster summary — shards, databases, chunk distribution.","kind":"exec","risk":"low","side_effects":["Reads sharding metadata.","Read-only."],"args":[],"examples":[{"title":"Shard cluster status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");sh.status(true)'"]}},{"id":"mongo.top","title":"db.adminCommand({top:1})","summary":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","description":"Show per-collection time spent in reads/writes/commands. Mongo \"top\" for query traffic.","kind":"exec","risk":"low","side_effects":["One top command.","Read-only."],"args":[],"examples":[{"title":"Per-coll time","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.adminCommand({top:1}))'"]}},{"id":"mongo.wiredtiger_cache","title":"WiredTiger cache pressure (serverStatus.wiredTiger.cache)","summary":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","description":"Show WiredTiger cache pressure — bytes currently in cache vs maximum configured, tracked dirty bytes, pages evicted by application threads, and pages read into cache. Application-thread eviction and a full dirty cache indicate memory pressure.","kind":"exec","risk":"low","side_effects":["One serverStatus command.","Read-only."],"args":[],"examples":[{"title":"Cache stats","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mongosh '--nodb' '--quiet' '--eval' 'db=new Mongo(process.env.MONGO_URI).getDB(\"admin\");JSON.stringify(db.serverStatus().wiredTiger.cache)'"]}}]}]},{"id":"multipath","name":"Device-mapper multipath","version":"0.1.4","description":"Inspect device-mapper multipath: the multipath topology (multipath -ll), the effective config (multipath -t), and live path + map state queried from the running multipathd. Read-only.","vendor":"emisar","homepage":"https://emisar.dev/packs/multipath","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/multipath","content_hash":"sha256:82fa3008872d9aecfdc36387fa6e590f73828f40fb6c799d7bcfc8c75de12274","tarball_url":"https://registry.emisar.dev/v1/packs/multipath/0.1.4/82fa3008872d9aecfdc36387fa6e590f73828f40fb6c799d7bcfc8c75de12274/pack.tar.gz","requires":{"os":["linux"],"binaries":["multipath","multipathd"]},"detect":{"binaries":["multipath"],"processes":["multipathd"],"ports":[]},"setup":{"summary":"Reads the local host's multipath topology and queries the running multipathd — no credentials needed. multipath and multipathd both need root (device-mapper + the daemon control socket).","notes":["The `multipathd show ...` actions query the running daemon over its control socket; if multipathd isn't running they return an error."],"host_access":[{"actions":["multipath.topology","multipath.config","multipath.daemon_paths","multipath.daemon_maps"],"requirement":"Read device-mapper state and the multipathd control socket as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-multipath-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root and can reach host block devices and the multipath daemon, including actions from other installed packs."}]}],"verify":"multipath.topology"},"actions":[{"id":"multipath.config","title":"multipath -t","summary":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","description":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","kind":"exec","risk":"low","side_effects":["One config dump.","Read-only."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"multipath","argv":["-t"]}},{"id":"multipath.daemon_maps","title":"multipathd show maps","summary":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","description":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Map states","args":{}}],"search_terms":[],"command":{"binary":"multipathd","argv":["show","maps"]}},{"id":"multipath.daemon_paths","title":"multipathd show paths","summary":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","description":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Path states","args":{}}],"search_terms":["failed paths"],"command":{"binary":"multipathd","argv":["show","paths"]}},{"id":"multipath.topology","title":"multipath -ll","summary":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","description":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","kind":"exec","risk":"low","side_effects":["One multipath read.","Read-only."],"args":[],"examples":[{"title":"Show multipath devices + paths","args":{}}],"search_terms":["path failure","all paths down","lun paths"],"command":{"binary":"multipath","argv":["-ll"]}}],"previous_versions":[{"version":"0.1.3","content_hash":"sha256:495a931bff2a3c806b1e24dec5e872b941999c258c2f8c02a9cc172704e6e3ea","tarball_url":"https://registry.emisar.dev/v1/packs/multipath/0.1.3/495a931bff2a3c806b1e24dec5e872b941999c258c2f8c02a9cc172704e6e3ea/pack.tar.gz","actions":[{"id":"multipath.config","title":"multipath -t","summary":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","description":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","kind":"exec","risk":"low","side_effects":["One config dump.","Read-only."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"multipath","argv":["-t"]}},{"id":"multipath.daemon_maps","title":"multipathd show maps","summary":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","description":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Map states","args":{}}],"search_terms":[],"command":{"binary":"multipathd","argv":["show","maps"]}},{"id":"multipath.daemon_paths","title":"multipathd show paths","summary":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","description":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Path states","args":{}}],"search_terms":["failed paths"],"command":{"binary":"multipathd","argv":["show","paths"]}},{"id":"multipath.topology","title":"multipath -ll","summary":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","description":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","kind":"exec","risk":"low","side_effects":["One multipath read.","Read-only."],"args":[],"examples":[{"title":"Show multipath devices + paths","args":{}}],"search_terms":["path failure","all paths down","lun paths"],"command":{"binary":"multipath","argv":["-ll"]}}]},{"version":"0.1.2","content_hash":"sha256:11418e0a098f4d67f2b961d17fbaeab15b71110f95865f7a176fdc02e4fc1223","tarball_url":"https://registry.emisar.dev/v1/packs/multipath/0.1.2/11418e0a098f4d67f2b961d17fbaeab15b71110f95865f7a176fdc02e4fc1223/pack.tar.gz","actions":[{"id":"multipath.config","title":"multipath -t","summary":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","description":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","kind":"exec","risk":"low","side_effects":["One config dump.","Read-only."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"multipath","argv":["-t"]}},{"id":"multipath.daemon_maps","title":"multipathd show maps","summary":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","description":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Map states","args":{}}],"search_terms":[],"command":{"binary":"multipathd","argv":["show","maps"]}},{"id":"multipath.daemon_paths","title":"multipathd show paths","summary":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","description":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Path states","args":{}}],"search_terms":["failed paths"],"command":{"binary":"multipathd","argv":["show","paths"]}},{"id":"multipath.topology","title":"multipath -ll","summary":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","description":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","kind":"exec","risk":"low","side_effects":["One multipath read.","Read-only."],"args":[],"examples":[{"title":"Show multipath devices + paths","args":{}}],"search_terms":["path failure","all paths down","lun paths"],"command":{"binary":"multipath","argv":["-ll"]}}]},{"version":"0.1.1","content_hash":"sha256:406e7d3bbdeb3f931e74048ba2249878470739826d7689e27be26702fd77a2dc","tarball_url":"https://registry.emisar.dev/v1/packs/multipath/0.1.1/406e7d3bbdeb3f931e74048ba2249878470739826d7689e27be26702fd77a2dc/pack.tar.gz","actions":[{"id":"multipath.config","title":"multipath -t","summary":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","description":"Show effective multipathd configuration (merged built-in defaults + multipath.conf).","kind":"exec","risk":"low","side_effects":["One config dump.","Read-only."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"multipath","argv":["-t"]}},{"id":"multipath.daemon_maps","title":"multipathd show maps","summary":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","description":"List multipath maps from the running multipathd (name, wwid, path count, queueing state).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Map states","args":{}}],"search_terms":[],"command":{"binary":"multipathd","argv":["show","maps"]}},{"id":"multipath.daemon_paths","title":"multipathd show paths","summary":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","description":"Show per-path state from the running multipathd (dev, dm state, path checker, latency).","kind":"exec","risk":"low","side_effects":["One multipathd query.","Read-only."],"args":[],"examples":[{"title":"Path states","args":{}}],"search_terms":[],"command":{"binary":"multipathd","argv":["show","paths"]}},{"id":"multipath.topology","title":"multipath -ll","summary":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","description":"Show full multipath topology — each multipath device (wwid, alias, vendor/product), its path groups, and per-path state (active/enabled, dm status, path checker result).","kind":"exec","risk":"low","side_effects":["One multipath read.","Read-only."],"args":[],"examples":[{"title":"Show multipath devices + paths","args":{}}],"search_terms":[],"command":{"binary":"multipath","argv":["-ll"]}}]}]},{"id":"mysql","name":"MySQL / MariaDB operations","version":"0.1.10","description":"Read-only MySQL diagnostics plus narrow operator actions for killing queries, flushing logs, and analyzing tables. Authenticates via ~/.my.cnf or MYSQL_PWD env var on the runner host — never via per-call credentials over the wire.","vendor":"emisar","homepage":"https://emisar.dev/packs/mysql","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/mysql","content_hash":"sha256:8a1fbe3b051a57a00ce29a8f0e854d44ea27ca5a913359a92a0a41206366782c","tarball_url":"https://registry.emisar.dev/v1/packs/mysql/0.1.10/8a1fbe3b051a57a00ce29a8f0e854d44ea27ca5a913359a92a0a41206366782c/pack.tar.gz","requires":{"os":["linux"],"binaries":["mysql"]},"detect":{"binaries":[],"processes":["mysqld","mariadbd"],"ports":[3306]},"setup":{"summary":"The mysql client reads its password and connection target from its own environment variables on the runner host; the actions pass no connection flags. The username is not taken from the environment — it comes from `~/.my.cnf` or defaults to the runner's OS user.","env":[{"name":"MYSQL_PWD","description":"Password for the connecting user. Prefer `~/.my.cnf` instead — env-var passwords are visible in the process list."},{"name":"MYSQL_HOST","description":"Server host for TCP connections.","default":"localhost"},{"name":"MYSQL_TCP_PORT","description":"Server TCP port.","default":"3306"},{"name":"MYSQL_UNIX_PORT","description":"Unix socket path, used when connecting to localhost.","example":"/var/run/mysqld/mysqld.sock"}],"notes":["Cleanest credential store: `~/.my.cnf` (mode 0600) on the runner host with [client] user/password/host — read from disk, so it needs no `inherit_env` entry.","The username is never read from the environment; set it in `~/.my.cnf`, otherwise it defaults to the runner's OS user.","Mutators (kill_query, kill_connection, flush_logs, analyze_table, optimize_table) need a user with PROCESS/RELOAD and the relevant table privileges."],"verify":"mysql.uptime"},"actions":[{"id":"mysql.analyze_table","title":"ANALYZE TABLE","summary":"Refresh the optimizer statistics for one table. Per-table only; cannot wildcard.","description":"Refresh the optimizer statistics for one table. Per-table only; cannot wildcard.","kind":"exec","risk":"medium","side_effects":["Briefly holds a read lock on the table.","Refreshes index cardinality stats."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Refresh stats for orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","ANALYZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.binlog_positions","title":"Binary log files","summary":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","description":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","kind":"exec","risk":"low","side_effects":["One SHOW BINARY LOGS.","Read-only."],"args":[],"examples":[{"title":"Binlogs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW BINARY LOGS"]}},{"id":"mysql.connections_summary","title":"Connection counts + cap","summary":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","description":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","kind":"exec","risk":"low","side_effects":["One SHOW STATUS + one SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Connection summary","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE 'Threads_%'; SHOW GLOBAL VARIABLES LIKE 'max_connections'; SELECT SUBSTRING_INDEX(host, ':', 1) AS client, count(*) AS conns FROM information_schema.processlist GROUP BY client ORDER BY conns DESC;"]}},{"id":"mysql.db_sizes","title":"Database sizes","summary":"Show per-database data + index size summary. Read-only.","description":"Show per-database data + index size summary. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[],"examples":[{"title":"Per-DB sizes","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, ROUND(SUM(data_length)/1024/1024, 2) AS data_mb, ROUND(SUM(index_length)/1024/1024, 2) AS idx_mb, ROUND(SUM(data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length+index_length) DESC;"]}},{"id":"mysql.engines","title":"SHOW ENGINES","summary":"List available storage engines and which is default. Read-only.","description":"List available storage engines and which is default. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINES.","Read-only."],"args":[],"examples":[{"title":"Engines","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINES"]}},{"id":"mysql.flush_logs","title":"FLUSH LOGS","summary":"Close and reopen all log files (general, slow, error, binary). Use after rotating with logrotate.","description":"Close and reopen all log files (general, slow, error, binary). Use after rotating with logrotate.","kind":"exec","risk":"medium","side_effects":["Log files closed and reopened.","Binlog rolls forward."],"args":[],"examples":[{"title":"Roll logs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH LOGS"]}},{"id":"mysql.flush_status","title":"FLUSH STATUS","summary":"Reset the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","description":"Reset the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","kind":"exec","risk":"medium","side_effects":["Most GLOBAL STATUS counters reset to 0.","Some session-level counters also affected."],"args":[],"examples":[{"title":"Reset counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH STATUS"]}},{"id":"mysql.gtid_executed","title":"GTID executed set","summary":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","description":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"GTID set","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT @@GLOBAL.gtid_executed"]}},{"id":"mysql.index_unused","title":"Unused indexes","summary":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","description":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Indexes nobody reads","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, index_name FROM performance_schema.table_io_waits_summary_by_index_usage WHERE index_name IS NOT NULL AND count_star = 0 AND object_schema NOT IN ('mysql','performance_schema') ORDER BY object_schema, object_name;"]}},{"id":"mysql.innodb_status","title":"SHOW ENGINE INNODB STATUS","summary":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic. Rated medium because the status blob embeds live SQL from the latest deadlock and active transactions, which can include literal request values no redaction list can enumerate.","description":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic. Rated medium because the status blob embeds live SQL from the latest deadlock and active transactions, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SHOW ENGINE INNODB STATUS.","Read-only."],"args":[],"examples":[{"title":"InnoDB engine state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINE INNODB STATUS\\G"]}},{"id":"mysql.kill_connection","title":"KILL (terminate connection)","summary":"Terminate one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","description":"Terminate one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","kind":"exec","risk":"high","side_effects":["Target connection closed.","In-flight transaction on it rolls back."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Kill connection 12345","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL {{ args.thread_id }}"]}},{"id":"mysql.kill_query","title":"KILL QUERY (cancel statement)","summary":"Cancel the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","description":"Cancel the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","kind":"exec","risk":"high","side_effects":["Target connection's current query is aborted.","Connection stays open; subsequent queries can be issued."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Cancel a runaway SELECT","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL QUERY {{ args.thread_id }}"]}},{"id":"mysql.lock_waits","title":"Lock-wait graph","summary":"Join performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","description":"Join performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Blocking transactions","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT r.trx_id AS waiting_trx, r.trx_mysql_thread_id AS waiting_thread, r.trx_query AS waiting_query, b.trx_id AS blocking_trx, b.trx_mysql_thread_id AS blocking_thread, b.trx_query AS blocking_query FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON w.REQUESTING_ENGINE_TRANSACTION_ID = r.trx_id JOIN information_schema.innodb_trx b ON w.BLOCKING_ENGINE_TRANSACTION_ID = b.trx_id;"]}},{"id":"mysql.master_status","title":"SHOW MASTER STATUS","summary":"Show current binary log file, position, and GTID set on the primary. Read-only.","description":"Show current binary log file, position, and GTID set on the primary. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW MASTER STATUS.","Read-only."],"args":[],"examples":[{"title":"Primary binlog state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW MASTER STATUS"]}},{"id":"mysql.open_tables","title":"SHOW OPEN TABLES","summary":"List tables currently in the table cache. Read-only.","description":"List tables currently in the table cache. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW OPEN TABLES.","Read-only."],"args":[],"examples":[{"title":"Open tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW OPEN TABLES"]}},{"id":"mysql.optimize_table","title":"OPTIMIZE TABLE","summary":"Rebuild the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","description":"Rebuild the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","kind":"exec","risk":"high","side_effects":["May briefly lock the table (engine-dependent).","Reclaims data + index disk space."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Reclaim space on orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","OPTIMIZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.processlist","title":"SHOW FULL PROCESSLIST","summary":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\" Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\" Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Active connections","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW FULL PROCESSLIST"]}},{"id":"mysql.replica_status","title":"SHOW REPLICA STATUS","summary":"Read SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","description":"Read SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","kind":"exec","risk":"low","side_effects":["One SHOW REPLICA STATUS.","Read-only."],"args":[],"examples":[{"title":"Replica state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mysql -e 'SHOW REPLICA STATUS\\G' 2>/dev/null || mysql -e 'SHOW SLAVE STATUS\\G'"]}},{"id":"mysql.slow_queries","title":"Top slow query digests","summary":"Read performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled. Stays low — DIGEST_TEXT is a normalized fingerprint (literal values replaced with `?`), so the output is the query shape and table/column names, not real request data.","description":"Read performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled. Stays low — DIGEST_TEXT is a normalized fingerprint (literal values replaced with `?`), so the output is the query shape and table/column names, not real request data.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many digests.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top 20 slow queries","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT COUNT_STAR AS calls, ROUND(AVG_TIMER_WAIT/1e9, 2) AS avg_ms, ROUND(SUM_TIMER_WAIT/1e9, 2) AS total_ms, LEFT(DIGEST_TEXT, 200) AS query FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT IS NOT NULL ORDER BY AVG_TIMER_WAIT DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.status","title":"SHOW GLOBAL STATUS (filtered)","summary":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","description":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL STATUS.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"Threads_%","description":"SHOW STATUS LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"Thread counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE '{{ args.pattern }}'"]}},{"id":"mysql.table_io_summary","title":"Top tables by IO wait","summary":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","description":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"IO-heavy tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, count_read, count_write, ROUND(sum_timer_wait/1e9, 2) AS total_ms FROM performance_schema.table_io_waits_summary_by_table WHERE object_schema NOT IN ('mysql','performance_schema') ORDER BY sum_timer_wait DESC LIMIT 30;"]}},{"id":"mysql.table_sizes","title":"Top tables by total size","summary":"List top N tables ordered by (data + index) size in bytes. Read-only.","description":"List top N tables ordered by (data + index) size in bytes. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many.","validation":{"min":1,"max":500}}],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, table_name, table_rows, ROUND(data_length/1024/1024, 2) AS data_mb, ROUND(index_length/1024/1024, 2) AS idx_mb, ROUND((data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY data_length+index_length DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.uptime","title":"Uptime + version","summary":"Return SELECT VERSION() and uptime from SHOW STATUS. Read-only.","description":"Return SELECT VERSION() and uptime from SHOW STATUS. Read-only.","kind":"exec","risk":"low","side_effects":["Two SELECTs.","Read-only."],"args":[],"examples":[{"title":"Liveness + version","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT VERSION(); SHOW STATUS LIKE 'Uptime';"]}},{"id":"mysql.users_grants","title":"List users + grants summary","summary":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","description":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","kind":"exec","risk":"low","side_effects":["One SELECT mysql.user.","Read-only."],"args":[],"examples":[{"title":"All users","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT user, host, plugin, account_locked, password_last_changed FROM mysql.user ORDER BY user, host"]}},{"id":"mysql.variables","title":"SHOW GLOBAL VARIABLES (filtered)","summary":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","description":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL VARIABLES.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"innodb_%","description":"SHOW VARIABLES LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"InnoDB settings","args":{}},{"title":"max_connections","args":{"pattern":"max_%"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL VARIABLES LIKE '{{ args.pattern }}'"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:a13e89afa6a7094657e8a69d12c15754ee8d524aa411fb9569f7fba5c2c57e13","tarball_url":"https://registry.emisar.dev/v1/packs/mysql/0.1.9/a13e89afa6a7094657e8a69d12c15754ee8d524aa411fb9569f7fba5c2c57e13/pack.tar.gz","actions":[{"id":"mysql.analyze_table","title":"ANALYZE TABLE","summary":"Refresh the optimizer statistics for one table. Per-table only; cannot wildcard.","description":"Refresh the optimizer statistics for one table. Per-table only; cannot wildcard.","kind":"exec","risk":"medium","side_effects":["Briefly holds a read lock on the table.","Refreshes index cardinality stats."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Refresh stats for orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","ANALYZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.binlog_positions","title":"Binary log files","summary":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","description":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","kind":"exec","risk":"low","side_effects":["One SHOW BINARY LOGS.","Read-only."],"args":[],"examples":[{"title":"Binlogs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW BINARY LOGS"]}},{"id":"mysql.connections_summary","title":"Connection counts + cap","summary":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","description":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","kind":"exec","risk":"low","side_effects":["One SHOW STATUS + one SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Connection summary","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE 'Threads_%'; SHOW GLOBAL VARIABLES LIKE 'max_connections'; SELECT SUBSTRING_INDEX(host, ':', 1) AS client, count(*) AS conns FROM information_schema.processlist GROUP BY client ORDER BY conns DESC;"]}},{"id":"mysql.db_sizes","title":"Database sizes","summary":"Show per-database data + index size summary. Read-only.","description":"Show per-database data + index size summary. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[],"examples":[{"title":"Per-DB sizes","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, ROUND(SUM(data_length)/1024/1024, 2) AS data_mb, ROUND(SUM(index_length)/1024/1024, 2) AS idx_mb, ROUND(SUM(data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length+index_length) DESC;"]}},{"id":"mysql.engines","title":"SHOW ENGINES","summary":"List available storage engines and which is default. Read-only.","description":"List available storage engines and which is default. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINES.","Read-only."],"args":[],"examples":[{"title":"Engines","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINES"]}},{"id":"mysql.flush_logs","title":"FLUSH LOGS","summary":"Close and reopen all log files (general, slow, error, binary). Use after rotating with logrotate.","description":"Close and reopen all log files (general, slow, error, binary). Use after rotating with logrotate.","kind":"exec","risk":"medium","side_effects":["Log files closed and reopened.","Binlog rolls forward."],"args":[],"examples":[{"title":"Roll logs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH LOGS"]}},{"id":"mysql.flush_status","title":"FLUSH STATUS","summary":"Reset the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","description":"Reset the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","kind":"exec","risk":"medium","side_effects":["Most GLOBAL STATUS counters reset to 0.","Some session-level counters also affected."],"args":[],"examples":[{"title":"Reset counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH STATUS"]}},{"id":"mysql.gtid_executed","title":"GTID executed set","summary":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","description":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"GTID set","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT @@GLOBAL.gtid_executed"]}},{"id":"mysql.index_unused","title":"Unused indexes","summary":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","description":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Indexes nobody reads","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, index_name FROM performance_schema.table_io_waits_summary_by_index_usage WHERE index_name IS NOT NULL AND count_star = 0 AND object_schema NOT IN ('mysql','performance_schema') ORDER BY object_schema, object_name;"]}},{"id":"mysql.innodb_status","title":"SHOW ENGINE INNODB STATUS","summary":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic.","description":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINE INNODB STATUS.","Read-only."],"args":[],"examples":[{"title":"InnoDB engine state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINE INNODB STATUS\\G"]}},{"id":"mysql.kill_connection","title":"KILL (terminate connection)","summary":"Terminate one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","description":"Terminate one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","kind":"exec","risk":"high","side_effects":["Target connection closed.","In-flight transaction on it rolls back."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Kill connection 12345","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL {{ args.thread_id }}"]}},{"id":"mysql.kill_query","title":"KILL QUERY (cancel statement)","summary":"Cancel the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","description":"Cancel the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","kind":"exec","risk":"high","side_effects":["Target connection's current query is aborted.","Connection stays open; subsequent queries can be issued."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Cancel a runaway SELECT","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL QUERY {{ args.thread_id }}"]}},{"id":"mysql.lock_waits","title":"Lock-wait graph","summary":"Join performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","description":"Join performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Blocking transactions","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT r.trx_id AS waiting_trx, r.trx_mysql_thread_id AS waiting_thread, r.trx_query AS waiting_query, b.trx_id AS blocking_trx, b.trx_mysql_thread_id AS blocking_thread, b.trx_query AS blocking_query FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON w.REQUESTING_ENGINE_TRANSACTION_ID = r.trx_id JOIN information_schema.innodb_trx b ON w.BLOCKING_ENGINE_TRANSACTION_ID = b.trx_id;"]}},{"id":"mysql.master_status","title":"SHOW MASTER STATUS","summary":"Show current binary log file, position, and GTID set on the primary. Read-only.","description":"Show current binary log file, position, and GTID set on the primary. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW MASTER STATUS.","Read-only."],"args":[],"examples":[{"title":"Primary binlog state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW MASTER STATUS"]}},{"id":"mysql.open_tables","title":"SHOW OPEN TABLES","summary":"List tables currently in the table cache. Read-only.","description":"List tables currently in the table cache. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW OPEN TABLES.","Read-only."],"args":[],"examples":[{"title":"Open tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW OPEN TABLES"]}},{"id":"mysql.optimize_table","title":"OPTIMIZE TABLE","summary":"Rebuild the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","description":"Rebuild the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","kind":"exec","risk":"high","side_effects":["May briefly lock the table (engine-dependent).","Reclaims data + index disk space."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Reclaim space on orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","OPTIMIZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.processlist","title":"SHOW FULL PROCESSLIST","summary":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\"","description":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\"","kind":"exec","risk":"low","side_effects":["One SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Active connections","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW FULL PROCESSLIST"]}},{"id":"mysql.replica_status","title":"SHOW REPLICA STATUS","summary":"Read SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","description":"Read SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","kind":"exec","risk":"low","side_effects":["One SHOW REPLICA STATUS.","Read-only."],"args":[],"examples":[{"title":"Replica state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mysql -e 'SHOW REPLICA STATUS\\G' 2>/dev/null || mysql -e 'SHOW SLAVE STATUS\\G'"]}},{"id":"mysql.slow_queries","title":"Top slow query digests","summary":"Read performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled.","description":"Read performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many digests.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top 20 slow queries","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT COUNT_STAR AS calls, ROUND(AVG_TIMER_WAIT/1e9, 2) AS avg_ms, ROUND(SUM_TIMER_WAIT/1e9, 2) AS total_ms, LEFT(DIGEST_TEXT, 200) AS query FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT IS NOT NULL ORDER BY AVG_TIMER_WAIT DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.status","title":"SHOW GLOBAL STATUS (filtered)","summary":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","description":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL STATUS.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"Threads_%","description":"SHOW STATUS LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"Thread counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE '{{ args.pattern }}'"]}},{"id":"mysql.table_io_summary","title":"Top tables by IO wait","summary":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","description":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"IO-heavy tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, count_read, count_write, ROUND(sum_timer_wait/1e9, 2) AS total_ms FROM performance_schema.table_io_waits_summary_by_table WHERE object_schema NOT IN ('mysql','performance_schema') ORDER BY sum_timer_wait DESC LIMIT 30;"]}},{"id":"mysql.table_sizes","title":"Top tables by total size","summary":"List top N tables ordered by (data + index) size in bytes. Read-only.","description":"List top N tables ordered by (data + index) size in bytes. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many.","validation":{"min":1,"max":500}}],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, table_name, table_rows, ROUND(data_length/1024/1024, 2) AS data_mb, ROUND(index_length/1024/1024, 2) AS idx_mb, ROUND((data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY data_length+index_length DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.uptime","title":"Uptime + version","summary":"Return SELECT VERSION() and uptime from SHOW STATUS. Read-only.","description":"Return SELECT VERSION() and uptime from SHOW STATUS. Read-only.","kind":"exec","risk":"low","side_effects":["Two SELECTs.","Read-only."],"args":[],"examples":[{"title":"Liveness + version","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT VERSION(); SHOW STATUS LIKE 'Uptime';"]}},{"id":"mysql.users_grants","title":"List users + grants summary","summary":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","description":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","kind":"exec","risk":"low","side_effects":["One SELECT mysql.user.","Read-only."],"args":[],"examples":[{"title":"All users","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT user, host, plugin, account_locked, password_last_changed FROM mysql.user ORDER BY user, host"]}},{"id":"mysql.variables","title":"SHOW GLOBAL VARIABLES (filtered)","summary":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","description":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL VARIABLES.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"innodb_%","description":"SHOW VARIABLES LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"InnoDB settings","args":{}},{"title":"max_connections","args":{"pattern":"max_%"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL VARIABLES LIKE '{{ args.pattern }}'"]}}]},{"version":"0.1.6","content_hash":"sha256:6939a1f90efe600a2b2607082a48fb9ad736a1d05d7b9a4a14d0ebf231b64521","tarball_url":"https://registry.emisar.dev/v1/packs/mysql/0.1.6/6939a1f90efe600a2b2607082a48fb9ad736a1d05d7b9a4a14d0ebf231b64521/pack.tar.gz","actions":[{"id":"mysql.analyze_table","title":"ANALYZE TABLE","summary":"Refresh the optimizer statistics for one table. Per-table only; cannot wildcard.","description":"Refresh the optimizer statistics for one table. Per-table only; cannot wildcard.","kind":"exec","risk":"medium","side_effects":["Briefly holds a read lock on the table.","Refreshes index cardinality stats."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Refresh stats for orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","ANALYZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.binlog_positions","title":"Binary log files","summary":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","description":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","kind":"exec","risk":"low","side_effects":["One SHOW BINARY LOGS.","Read-only."],"args":[],"examples":[{"title":"Binlogs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW BINARY LOGS"]}},{"id":"mysql.connections_summary","title":"Connection counts + cap","summary":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","description":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","kind":"exec","risk":"low","side_effects":["One SHOW STATUS + one SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Connection summary","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE 'Threads_%'; SHOW GLOBAL VARIABLES LIKE 'max_connections'; SELECT SUBSTRING_INDEX(host, ':', 1) AS client, count(*) AS conns FROM information_schema.processlist GROUP BY client ORDER BY conns DESC;"]}},{"id":"mysql.db_sizes","title":"Database sizes","summary":"Show per-database data + index size summary. Read-only.","description":"Show per-database data + index size summary. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[],"examples":[{"title":"Per-DB sizes","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, ROUND(SUM(data_length)/1024/1024, 2) AS data_mb, ROUND(SUM(index_length)/1024/1024, 2) AS idx_mb, ROUND(SUM(data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length+index_length) DESC;"]}},{"id":"mysql.engines","title":"SHOW ENGINES","summary":"List available storage engines and which is default. Read-only.","description":"List available storage engines and which is default. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINES.","Read-only."],"args":[],"examples":[{"title":"Engines","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINES"]}},{"id":"mysql.flush_logs","title":"FLUSH LOGS","summary":"Close and reopen all log files (general, slow, error, binary). Use after rotating with logrotate.","description":"Close and reopen all log files (general, slow, error, binary). Use after rotating with logrotate.","kind":"exec","risk":"medium","side_effects":["Log files closed and reopened.","Binlog rolls forward."],"args":[],"examples":[{"title":"Roll logs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH LOGS"]}},{"id":"mysql.flush_status","title":"FLUSH STATUS","summary":"Reset the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","description":"Reset the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","kind":"exec","risk":"medium","side_effects":["Most GLOBAL STATUS counters reset to 0.","Some session-level counters also affected."],"args":[],"examples":[{"title":"Reset counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH STATUS"]}},{"id":"mysql.gtid_executed","title":"GTID executed set","summary":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","description":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"GTID set","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT @@GLOBAL.gtid_executed"]}},{"id":"mysql.index_unused","title":"Unused indexes","summary":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","description":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Indexes nobody reads","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, index_name FROM performance_schema.table_io_waits_summary_by_index_usage WHERE index_name IS NOT NULL AND count_star = 0 AND object_schema NOT IN ('mysql','performance_schema') ORDER BY object_schema, object_name;"]}},{"id":"mysql.innodb_status","title":"SHOW ENGINE INNODB STATUS","summary":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic.","description":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINE INNODB STATUS.","Read-only."],"args":[],"examples":[{"title":"InnoDB engine state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINE INNODB STATUS\\G"]}},{"id":"mysql.kill_connection","title":"KILL (terminate connection)","summary":"Terminate one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","description":"Terminate one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","kind":"exec","risk":"high","side_effects":["Target connection closed.","In-flight transaction on it rolls back."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Kill connection 12345","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL {{ args.thread_id }}"]}},{"id":"mysql.kill_query","title":"KILL QUERY (cancel statement)","summary":"Cancel the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","description":"Cancel the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","kind":"exec","risk":"high","side_effects":["Target connection's current query is aborted.","Connection stays open; subsequent queries can be issued."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Cancel a runaway SELECT","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL QUERY {{ args.thread_id }}"]}},{"id":"mysql.lock_waits","title":"Lock-wait graph","summary":"Join performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","description":"Join performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Blocking transactions","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT r.trx_id AS waiting_trx, r.trx_mysql_thread_id AS waiting_thread, r.trx_query AS waiting_query, b.trx_id AS blocking_trx, b.trx_mysql_thread_id AS blocking_thread, b.trx_query AS blocking_query FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON w.REQUESTING_ENGINE_TRANSACTION_ID = r.trx_id JOIN information_schema.innodb_trx b ON w.BLOCKING_ENGINE_TRANSACTION_ID = b.trx_id;"]}},{"id":"mysql.master_status","title":"SHOW MASTER STATUS","summary":"Show current binary log file, position, and GTID set on the primary. Read-only.","description":"Show current binary log file, position, and GTID set on the primary. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW MASTER STATUS.","Read-only."],"args":[],"examples":[{"title":"Primary binlog state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW MASTER STATUS"]}},{"id":"mysql.open_tables","title":"SHOW OPEN TABLES","summary":"List tables currently in the table cache. Read-only.","description":"List tables currently in the table cache. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW OPEN TABLES.","Read-only."],"args":[],"examples":[{"title":"Open tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW OPEN TABLES"]}},{"id":"mysql.optimize_table","title":"OPTIMIZE TABLE","summary":"Rebuild the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","description":"Rebuild the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","kind":"exec","risk":"high","side_effects":["May briefly lock the table (engine-dependent).","Reclaims data + index disk space."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Reclaim space on orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","OPTIMIZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.processlist","title":"SHOW FULL PROCESSLIST","summary":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\"","description":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\"","kind":"exec","risk":"low","side_effects":["One SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Active connections","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW FULL PROCESSLIST"]}},{"id":"mysql.replica_status","title":"SHOW REPLICA STATUS","summary":"Read SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","description":"Read SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","kind":"exec","risk":"low","side_effects":["One SHOW REPLICA STATUS.","Read-only."],"args":[],"examples":[{"title":"Replica state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mysql -e 'SHOW REPLICA STATUS\\G' 2>/dev/null || mysql -e 'SHOW SLAVE STATUS\\G'"]}},{"id":"mysql.slow_queries","title":"Top slow query digests","summary":"Read performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled.","description":"Read performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many digests.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top 20 slow queries","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT COUNT_STAR AS calls, ROUND(AVG_TIMER_WAIT/1e9, 2) AS avg_ms, ROUND(SUM_TIMER_WAIT/1e9, 2) AS total_ms, LEFT(DIGEST_TEXT, 200) AS query FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT IS NOT NULL ORDER BY AVG_TIMER_WAIT DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.status","title":"SHOW GLOBAL STATUS (filtered)","summary":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","description":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL STATUS.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"Threads_%","description":"SHOW STATUS LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"Thread counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE '{{ args.pattern }}'"]}},{"id":"mysql.table_io_summary","title":"Top tables by IO wait","summary":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","description":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"IO-heavy tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, count_read, count_write, ROUND(sum_timer_wait/1e9, 2) AS total_ms FROM performance_schema.table_io_waits_summary_by_table WHERE object_schema NOT IN ('mysql','performance_schema') ORDER BY sum_timer_wait DESC LIMIT 30;"]}},{"id":"mysql.table_sizes","title":"Top tables by total size","summary":"List top N tables ordered by (data + index) size in bytes. Read-only.","description":"List top N tables ordered by (data + index) size in bytes. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many.","validation":{"min":1,"max":500}}],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, table_name, table_rows, ROUND(data_length/1024/1024, 2) AS data_mb, ROUND(index_length/1024/1024, 2) AS idx_mb, ROUND((data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY data_length+index_length DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.uptime","title":"Uptime + version","summary":"Return SELECT VERSION() and uptime from SHOW STATUS. Read-only.","description":"Return SELECT VERSION() and uptime from SHOW STATUS. Read-only.","kind":"exec","risk":"low","side_effects":["Two SELECTs.","Read-only."],"args":[],"examples":[{"title":"Liveness + version","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT VERSION(); SHOW STATUS LIKE 'Uptime';"]}},{"id":"mysql.users_grants","title":"List users + grants summary","summary":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","description":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","kind":"exec","risk":"low","side_effects":["One SELECT mysql.user.","Read-only."],"args":[],"examples":[{"title":"All users","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT user, host, plugin, account_locked, password_last_changed FROM mysql.user ORDER BY user, host"]}},{"id":"mysql.variables","title":"SHOW GLOBAL VARIABLES (filtered)","summary":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","description":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL VARIABLES.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"innodb_%","description":"SHOW VARIABLES LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"InnoDB settings","args":{}},{"title":"max_connections","args":{"pattern":"max_%"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL VARIABLES LIKE '{{ args.pattern }}'"]}}]},{"version":"0.1.5","content_hash":"sha256:3e06d8e99fc00f404687bb6f755e84759bf6cc811f609682b1a22cba556c2215","tarball_url":"https://registry.emisar.dev/v1/packs/mysql/0.1.5/3e06d8e99fc00f404687bb6f755e84759bf6cc811f609682b1a22cba556c2215/pack.tar.gz","actions":[{"id":"mysql.analyze_table","title":"ANALYZE TABLE","summary":"Refreshes the optimizer statistics for one table. Per-table only; cannot wildcard.","description":"Refreshes the optimizer statistics for one table. Per-table only; cannot wildcard.","kind":"exec","risk":"medium","side_effects":["Briefly holds a read lock on the table.","Refreshes index cardinality stats."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Refresh stats for orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","ANALYZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.binlog_positions","title":"Binary log files","summary":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","description":"`SHOW BINARY LOGS` — every binlog file with its size. Use to plan binlog disk pressure.","kind":"exec","risk":"low","side_effects":["One SHOW BINARY LOGS.","Read-only."],"args":[],"examples":[{"title":"Binlogs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW BINARY LOGS"]}},{"id":"mysql.connections_summary","title":"Connection counts + cap","summary":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","description":"Show connected vs max_connections + breakdown by host. Use to check \"are we close to connection exhaustion?\"","kind":"exec","risk":"low","side_effects":["One SHOW STATUS + one SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Connection summary","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE 'Threads_%'; SHOW GLOBAL VARIABLES LIKE 'max_connections'; SELECT SUBSTRING_INDEX(host, ':', 1) AS client, count(*) AS conns FROM information_schema.processlist GROUP BY client ORDER BY conns DESC;"]}},{"id":"mysql.db_sizes","title":"Database sizes","summary":"Show per-database data + index size summary. Read-only.","description":"Show per-database data + index size summary. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[],"examples":[{"title":"Per-DB sizes","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, ROUND(SUM(data_length)/1024/1024, 2) AS data_mb, ROUND(SUM(index_length)/1024/1024, 2) AS idx_mb, ROUND(SUM(data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables GROUP BY table_schema ORDER BY SUM(data_length+index_length) DESC;"]}},{"id":"mysql.engines","title":"SHOW ENGINES","summary":"Lists available storage engines and which is default. Read-only.","description":"Lists available storage engines and which is default. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINES.","Read-only."],"args":[],"examples":[{"title":"Engines","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINES"]}},{"id":"mysql.flush_logs","title":"FLUSH LOGS","summary":"Closes and reopens all log files (general, slow, error, binary). Use after rotating with logrotate.","description":"Closes and reopens all log files (general, slow, error, binary). Use after rotating with logrotate.","kind":"exec","risk":"medium","side_effects":["Log files closed and reopened.","Binlog rolls forward."],"args":[],"examples":[{"title":"Roll logs","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH LOGS"]}},{"id":"mysql.flush_status","title":"FLUSH STATUS","summary":"Resets the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","description":"Resets the GLOBAL STATUS counters to zero. Use before a workload to get a clean rate measurement window.","kind":"exec","risk":"medium","side_effects":["Most GLOBAL STATUS counters reset to 0.","Some session-level counters also affected."],"args":[],"examples":[{"title":"Reset counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","FLUSH STATUS"]}},{"id":"mysql.gtid_executed","title":"GTID executed set","summary":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","description":"`SELECT @@GLOBAL.gtid_executed` — every GTID this server has applied. Use to compare primary vs replica progress.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"GTID set","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT @@GLOBAL.gtid_executed"]}},{"id":"mysql.index_unused","title":"Unused indexes","summary":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","description":"List indexes with zero reads since uptime — candidates for dropping (frees disk + speeds writes). Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Indexes nobody reads","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, index_name FROM performance_schema.table_io_waits_summary_by_index_usage WHERE index_name IS NOT NULL AND count_star = 0 AND object_schema NOT IN ('mysql','performance_schema') ORDER BY object_schema, object_name;"]}},{"id":"mysql.innodb_status","title":"SHOW ENGINE INNODB STATUS","summary":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic.","description":"Show full InnoDB engine status — buffer pool, latest deadlock detected, longest waiting transaction, undo space, log sequence number. The canonical \"InnoDB is sick\" diagnostic.","kind":"exec","risk":"low","side_effects":["One SHOW ENGINE INNODB STATUS.","Read-only."],"args":[],"examples":[{"title":"InnoDB engine state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW ENGINE INNODB STATUS\\G"]}},{"id":"mysql.kill_connection","title":"KILL (terminate connection)","summary":"Terminates one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","description":"Terminates one connection. Use to clean up a stuck/idle session. Client sees \"lost connection\" and must reconnect.","kind":"exec","risk":"high","side_effects":["Target connection closed.","In-flight transaction on it rolls back."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Kill connection 12345","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL {{ args.thread_id }}"]}},{"id":"mysql.kill_query","title":"KILL QUERY (cancel statement)","summary":"Cancels the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","description":"Cancels the currently-executing query on one connection. Connection survives — pair with `kill_connection` to terminate the session entirely.","kind":"exec","risk":"high","side_effects":["Target connection's current query is aborted.","Connection stays open; subsequent queries can be issued."],"args":[{"name":"thread_id","type":"integer","required":true,"description":"Thread ID (from processlist).","validation":{"min":1,"max":4294967295}}],"examples":[{"title":"Cancel a runaway SELECT","args":{"thread_id":12345}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","KILL QUERY {{ args.thread_id }}"]}},{"id":"mysql.lock_waits","title":"Lock-wait graph","summary":"Joins performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","description":"Joins performance_schema.data_lock_waits with data_locks to show who is blocking whom. Use before a kill_query — you want the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"Blocking transactions","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT r.trx_id AS waiting_trx, r.trx_mysql_thread_id AS waiting_thread, r.trx_query AS waiting_query, b.trx_id AS blocking_trx, b.trx_mysql_thread_id AS blocking_thread, b.trx_query AS blocking_query FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON w.REQUESTING_ENGINE_TRANSACTION_ID = r.trx_id JOIN information_schema.innodb_trx b ON w.BLOCKING_ENGINE_TRANSACTION_ID = b.trx_id;"]}},{"id":"mysql.master_status","title":"SHOW MASTER STATUS","summary":"Show current binary log file, position, and GTID set on the primary. Read-only.","description":"Show current binary log file, position, and GTID set on the primary. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW MASTER STATUS.","Read-only."],"args":[],"examples":[{"title":"Primary binlog state","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW MASTER STATUS"]}},{"id":"mysql.open_tables","title":"SHOW OPEN TABLES","summary":"List tables currently in the table cache. Read-only.","description":"List tables currently in the table cache. Read-only.","kind":"exec","risk":"low","side_effects":["One SHOW OPEN TABLES.","Read-only."],"args":[],"examples":[{"title":"Open tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW OPEN TABLES"]}},{"id":"mysql.optimize_table","title":"OPTIMIZE TABLE","summary":"Rebuilds the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","description":"Rebuilds the table to reclaim space and re-sort the clustered index. **Holds an exclusive lock for the duration** on non-InnoDB engines; InnoDB tables get an online ALTER. Per-table only.","kind":"exec","risk":"high","side_effects":["May briefly lock the table (engine-dependent).","Reclaims data + index disk space."],"args":[{"name":"database","type":"string","required":true,"description":"Database.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}},{"name":"table","type":"string","required":true,"description":"Table.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,63}$"}}],"examples":[{"title":"Reclaim space on orders","args":{"database":"app","table":"orders"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","OPTIMIZE TABLE `{{ args.database }}`.`{{ args.table }}`"]}},{"id":"mysql.processlist","title":"SHOW FULL PROCESSLIST","summary":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\"","description":"List every active connection with its current command, state, and full query. The first stop for \"what is the DB doing?\"","kind":"exec","risk":"low","side_effects":["One SHOW PROCESSLIST.","Read-only."],"args":[],"examples":[{"title":"Active connections","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW FULL PROCESSLIST"]}},{"id":"mysql.replica_status","title":"SHOW REPLICA STATUS","summary":"Reads SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","description":"Reads SHOW REPLICA STATUS (or SHOW SLAVE STATUS on old versions). Surfaces lag, last error, IO and SQL thread state, and binlog position. Returns 'not a replica' cleanly when this is a primary.","kind":"exec","risk":"low","side_effects":["One SHOW REPLICA STATUS.","Read-only."],"args":[],"examples":[{"title":"Replica state","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mysql -e 'SHOW REPLICA STATUS\\G' 2>/dev/null || mysql -e 'SHOW SLAVE STATUS\\G'"]}},{"id":"mysql.slow_queries","title":"Top slow query digests","summary":"Reads performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled.","description":"Reads performance_schema.events_statements_summary_by_digest — top N statement fingerprints by mean execution time. Requires performance_schema enabled.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many digests.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top 20 slow queries","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT COUNT_STAR AS calls, ROUND(AVG_TIMER_WAIT/1e9, 2) AS avg_ms, ROUND(SUM_TIMER_WAIT/1e9, 2) AS total_ms, LEFT(DIGEST_TEXT, 200) AS query FROM performance_schema.events_statements_summary_by_digest WHERE DIGEST_TEXT IS NOT NULL ORDER BY AVG_TIMER_WAIT DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.status","title":"SHOW GLOBAL STATUS (filtered)","summary":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","description":"Show global counters filtered by glob pattern. Default returns connection + thread counters.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL STATUS.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"Threads_%","description":"SHOW STATUS LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"Thread counters","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL STATUS LIKE '{{ args.pattern }}'"]}},{"id":"mysql.table_io_summary","title":"Top tables by IO wait","summary":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","description":"List top 30 tables ordered by total I/O wait time. Identifies tables driving disk pressure.","kind":"exec","risk":"low","side_effects":["One SELECT against performance_schema.","Read-only."],"args":[],"examples":[{"title":"IO-heavy tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT object_schema, object_name, count_read, count_write, ROUND(sum_timer_wait/1e9, 2) AS total_ms FROM performance_schema.table_io_waits_summary_by_table WHERE object_schema NOT IN ('mysql','performance_schema') ORDER BY sum_timer_wait DESC LIMIT 30;"]}},{"id":"mysql.table_sizes","title":"Top tables by total size","summary":"List top N tables ordered by (data + index) size in bytes. Read-only.","description":"List top N tables ordered by (data + index) size in bytes. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against information_schema.tables.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":30,"description":"How many.","validation":{"min":1,"max":500}}],"examples":[{"title":"Biggest tables","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT table_schema, table_name, table_rows, ROUND(data_length/1024/1024, 2) AS data_mb, ROUND(index_length/1024/1024, 2) AS idx_mb, ROUND((data_length+index_length)/1024/1024, 2) AS total_mb FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys') ORDER BY data_length+index_length DESC LIMIT {{ args.limit }};"]}},{"id":"mysql.uptime","title":"Uptime + version","summary":"Returns SELECT VERSION() and uptime from SHOW STATUS. Read-only.","description":"Returns SELECT VERSION() and uptime from SHOW STATUS. Read-only.","kind":"exec","risk":"low","side_effects":["Two SELECTs.","Read-only."],"args":[],"examples":[{"title":"Liveness + version","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-NBe","SELECT VERSION(); SHOW STATUS LIKE 'Uptime';"]}},{"id":"mysql.users_grants","title":"List users + grants summary","summary":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","description":"List user + host pairs from mysql.user. Doesn't dump grants (volume) — use for audit \"who has accounts?\"","kind":"exec","risk":"low","side_effects":["One SELECT mysql.user.","Read-only."],"args":[],"examples":[{"title":"All users","args":{}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SELECT user, host, plugin, account_locked, password_last_changed FROM mysql.user ORDER BY user, host"]}},{"id":"mysql.variables","title":"SHOW GLOBAL VARIABLES (filtered)","summary":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","description":"Show global variables filtered by glob pattern. Default returns InnoDB + buffer settings.","kind":"exec","risk":"low","side_effects":["One SHOW GLOBAL VARIABLES.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"innodb_%","description":"SHOW VARIABLES LIKE pattern.","validation":{"pattern":"^[a-zA-Z0-9_%]{1,64}$"}}],"examples":[{"title":"InnoDB settings","args":{}},{"title":"max_connections","args":{"pattern":"max_%"}}],"search_terms":[],"command":{"binary":"mysql","argv":["-e","SHOW GLOBAL VARIABLES LIKE '{{ args.pattern }}'"]}}]}]},{"id":"network-tls","name":"Network + TLS diagnostics","version":"0.1.17","description":"DNS lookups, reachability probes, TLS certificate inspection, and HTTP timing tests. All read-only. Use for \"is X reachable?\" and \"what's the cert expiry on Y?\" questions.","vendor":"emisar","homepage":"https://emisar.dev/packs/network-tls","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/network-tls","content_hash":"sha256:abcc1193ab73b7c384d62fb270a7b832b4bee5e51de9f09d9ecc9d7ac6f8e299","tarball_url":"https://registry.emisar.dev/v1/packs/network-tls/0.1.17/abcc1193ab73b7c384d62fb270a7b832b4bee5e51de9f09d9ecc9d7ac6f8e299/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","dig","mtr","nc","openssl","ping","whois"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Probes the remote host, endpoint, or domain you pass as an action argument (host:port / name / URL) from the runner — no host-side credentials, but the runner needs outbound network reach to the target.","notes":["DNS/whois/ipinfo go to public resolvers and services; reachability and TLS probes need a network path from the runner to the target, so firewalls or egress rules can block them."],"host_access":[{"actions":["net.traceroute_mtr","net.ping_extended"],"requirement":"Open raw ICMP sockets with CAP_NET_RAW.","recipes":[{"name":"Grant CAP_NET_RAW to the Emisar service","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'AmbientCapabilities=CAP_NET_RAW' | sudo tee /etc/systemd/system/emisar.service.d/10-network-tls-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["systemctl show emisar --property=AmbientCapabilities --value | grep -Fwi cap_net_raw"],"impact":"Every Emisar action on this runner inherits CAP_NET_RAW and can open raw sockets — sending crafted packets and reading traffic on this host's interfaces — well beyond mtr and ping."}]}],"verify":"net.tls_cert_expiry"},"actions":[{"id":"net.dig_dnssec","title":"dig +dnssec (DNSSEC validation)","summary":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","description":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","kind":"exec","risk":"low","side_effects":["One DNS query with DO bit set.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"DNSSEC check","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+dnssec","{{ args.name }}"]}},{"id":"net.dig_record","title":"dig (DNS lookup)","summary":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","description":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name to look up.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SRV","PTR","SOA","CAA"]}},{"name":"resolver","type":"string","required":false,"default":"","description":"Resolver IP (empty = system default).","validation":{"pattern":"^[0-9a-fA-F.:]{0,45}$"}}],"examples":[{"title":"A record","args":{"name":"example.com"}},{"title":"MX record via Google's resolver","args":{"name":"example.com","resolver":"8.8.8.8","type":"MX"}}],"search_terms":["resolve hostname","dns not resolving"],"command":{"binary":"/bin/sh","argv":["-c","dig +short {{ args.type }} \"$1\" ${RES:+@$RES}","emisar","{{ args.name }}"]}},{"id":"net.dig_reverse","title":"dig -x (reverse DNS)","summary":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","description":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"PTR for 8.8.8.8","args":{"ip":"8.8.8.8"}}],"search_terms":[],"command":{"binary":"dig","argv":["-x","{{ args.ip }}"]}},{"id":"net.dig_trace","title":"dig +trace (full delegation chain)","summary":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","description":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","kind":"exec","risk":"low","side_effects":["Multiple DNS queries down the delegation tree.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"Trace delegation","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+trace","{{ args.name }}"]}},{"id":"net.http_headers","title":"HTTP response headers (curl -I)","summary":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","description":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","kind":"exec","risk":"low","side_effects":["One curl HEAD request.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Headers for example.com","args":{"url":"https://example.com/"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -q -sSIL --globoff --proto =http,https --proto-redir =http,https \"$@\" --max-time 10 \"$URL\""]}},{"id":"net.http_probe","title":"HTTP probe with timing","summary":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","description":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","kind":"exec","risk":"low","side_effects":["Outbound HTTP(S) to the URL.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL to probe.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"max_time","type":"integer","required":false,"default":10,"description":"Max total seconds.","validation":{"min":1,"max":60}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Probe example.com","args":{"url":"https://example.com/"}},{"title":"Probe an internal endpoint with a self-signed cert","args":{"insecure":true,"url":"https://10.0.0.5:8443/healthz"}}],"search_terms":["site down","website unreachable","is the site up","slow website"],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -q -sS --globoff --proto =http,https \"$@\" -o /dev/null --max-time \"$MAX_TIME\" -w \"http_code=%{http_code}\\nlookup=%{time_namelookup}\\nconnect=%{time_connect}\\nappconnect=%{time_appconnect}\\nstarttransfer=%{time_starttransfer}\\ntotal=%{time_total}\\nsize=%{size_download}\\n\" \"$URL\""]}},{"id":"net.ipinfo_lookup","title":"ipinfo (geo + ASN for an IP)","summary":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","description":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","kind":"exec","risk":"low","side_effects":["One HTTPS query to ipinfo.io.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"Lookup 1.1.1.1","args":{"ip":"1.1.1.1"}}],"search_terms":["who owns this ip"],"command":{"binary":"curl","argv":["-sfL","--globoff","--proto","=https","--proto-redir","=https","--max-time","10","https://ipinfo.io/{{ args.ip }}/json"]}},{"id":"net.ping_extended","title":"ping (with count + timeout)","summary":"Send N ICMP echo requests with explicit per-probe timeout. Needs CAP_NET_RAW on the runner identity where the host does not open `net.ipv4.ping_group_range`: ping ships setuid or file-capability elevation, and the runner's `no_new_privs` blocks both, so grant the capability from this pack's setup before enabling the action.","description":"Send N ICMP echo requests with explicit per-probe timeout. Needs CAP_NET_RAW on the runner identity where the host does not open `net.ipv4.ping_group_range`: ping ships setuid or file-capability elevation, and the runner's `no_new_privs` blocks both, so grant the capability from this pack's setup before enabling the action.","kind":"exec","risk":"low","side_effects":["Outbound ICMP.","Read-only.","Opens an ICMP socket, so it fails without CAP_NET_RAW on a host with a closed ping group range."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":10,"description":"Probes.","validation":{"min":1,"max":100}},{"name":"timeout","type":"integer","required":false,"default":2,"description":"Per-probe timeout seconds.","validation":{"min":1,"max":10}}],"examples":[{"title":"10 probes to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-W","{{ args.timeout }}","{{ args.host }}"]}},{"id":"net.tcp_probe","title":"Probe one TCP port","summary":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","description":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","kind":"script","risk":"low","side_effects":["One outbound TCP connection attempt.","Sends no application data and never listens."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP address.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9.:-]{0,251}[A-Za-z0-9])?$","max_length":253}},{"name":"port","type":"integer","required":true,"description":"Target TCP port.","validation":{"min":1,"max":65535}},{"name":"timeout","type":"integer","required":false,"default":3,"description":"Connect timeout in seconds.","validation":{"min":1,"max":30}}],"examples":[{"title":"Probe PostgreSQL from this runner","args":{"host":"database.internal","port":5432,"timeout":3}}],"search_terms":["connection refused","port unreachable","cross-host connectivity"]},{"id":"net.tls_cert_expiry","title":"TLS cert expiry probe","summary":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","description":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}},{"name":"sni","type":"string","required":false,"default":"","description":"SNI override (default = host).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{0,253}$"}}],"examples":[{"title":"Cert for example.com","args":{"host":"example.com"}}],"search_terms":["renewal","certificate error"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername ${SNI:-\"$1\"} </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer","emisar","{{ args.host }}"]}},{"id":"net.tls_chain_dump","title":"TLS chain dump","summary":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","description":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for example.com","args":{"host":"example.com"}}],"search_terms":["missing intermediate"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.host }}"]}},{"id":"net.tls_protocol_check","title":"TLS protocol support check","summary":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Fails outright when the target cannot be reached, and reports a version this runner's OpenSSL cannot offer as UNSUPPORTED-BY-CLIENT rather than REFUSED. Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","description":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Fails outright when the target cannot be reached, and reports a version this runner's OpenSSL cannot offer as UNSUPPORTED-BY-CLIENT rather than REFUSED. Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","kind":"script","risk":"low","side_effects":["One outbound reachability probe plus up to 4 version handshakes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"TLS support matrix","args":{"host":"example.com"}}],"search_terms":["weak tls"]},{"id":"net.traceroute_mtr","title":"mtr report (route + loss statistics)","summary":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report. Needs CAP_NET_RAW on the runner identity: mtr ships setuid or file-capability elevation, and the runner's `no_new_privs` blocks both, so grant the capability from this pack's setup before enabling the action.","description":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report. Needs CAP_NET_RAW on the runner identity: mtr ships setuid or file-capability elevation, and the runner's `no_new_privs` blocks both, so grant the capability from this pack's setup before enabling the action.","kind":"exec","risk":"low","side_effects":["Outbound ICMP/UDP probes.","Read-only.","Opens a raw socket, so it fails without CAP_NET_RAW on the runner identity."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"cycles","type":"integer","required":false,"default":5,"description":"Number of probe cycles.","validation":{"min":1,"max":30}}],"examples":[{"title":"5-cycle mtr to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["packet loss","network path","flaky connection"],"command":{"binary":"mtr","argv":["--report","--report-cycles={{ args.cycles }}","{{ args.host }}"]}},{"id":"net.whois_summary","title":"whois (registrar + expiry)","summary":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","description":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","kind":"exec","risk":"low","side_effects":["One whois query to the registry.","Read-only."],"args":[{"name":"domain","type":"string","required":true,"description":"Domain.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"whois example.com","args":{"domain":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","raw=$(whois \"$1\"); status=$?\nprintf '%s\\n' \"$raw\" | grep -iE 'registrar|registry|domain name|expir|name server|status' | head -30\nif [ \"$status\" -eq 0 ] && [ -n \"$raw\" ] && \\\n   ! printf '%s\\n' \"$raw\" | grep -qiE 'registrar|registry|domain name|expir|name server|status'; then\n  echo \"whois replied but no summary fields matched — raw reply may be a rate-limit or an unusual ccTLD format\" >&2\nfi\nexit $status\n","emisar","{{ args.domain }}"]}}],"previous_versions":[{"version":"0.1.15","content_hash":"sha256:e9da3187a025018b4da821e56b8ebdbf73245e420394698d8e1d99a23c8629e4","tarball_url":"https://registry.emisar.dev/v1/packs/network-tls/0.1.15/e9da3187a025018b4da821e56b8ebdbf73245e420394698d8e1d99a23c8629e4/pack.tar.gz","actions":[{"id":"net.dig_dnssec","title":"dig +dnssec (DNSSEC validation)","summary":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","description":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","kind":"exec","risk":"low","side_effects":["One DNS query with DO bit set.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"DNSSEC check","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+dnssec","{{ args.name }}"]}},{"id":"net.dig_record","title":"dig (DNS lookup)","summary":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","description":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name to look up.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SRV","PTR","SOA","CAA"]}},{"name":"resolver","type":"string","required":false,"default":"","description":"Resolver IP (empty = system default).","validation":{"pattern":"^[0-9a-fA-F.:]{0,45}$"}}],"examples":[{"title":"A record","args":{"name":"example.com"}},{"title":"MX record via Google's resolver","args":{"name":"example.com","resolver":"8.8.8.8","type":"MX"}}],"search_terms":["resolve hostname","dns not resolving"],"command":{"binary":"/bin/sh","argv":["-c","dig +short {{ args.type }} \"$1\" ${RES:+@$RES}","emisar","{{ args.name }}"]}},{"id":"net.dig_reverse","title":"dig -x (reverse DNS)","summary":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","description":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"PTR for 8.8.8.8","args":{"ip":"8.8.8.8"}}],"search_terms":[],"command":{"binary":"dig","argv":["-x","{{ args.ip }}"]}},{"id":"net.dig_trace","title":"dig +trace (full delegation chain)","summary":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","description":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","kind":"exec","risk":"low","side_effects":["Multiple DNS queries down the delegation tree.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"Trace delegation","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+trace","{{ args.name }}"]}},{"id":"net.http_headers","title":"HTTP response headers (curl -I)","summary":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","description":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","kind":"exec","risk":"low","side_effects":["One curl HEAD request.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Headers for example.com","args":{"url":"https://example.com/"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -sIL --globoff --proto =http,https --proto-redir =http,https \"$@\" --max-time 10 \"$URL\""]}},{"id":"net.http_probe","title":"HTTP probe with timing","summary":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","description":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","kind":"exec","risk":"low","side_effects":["Outbound HTTP(S) to the URL.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL to probe.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"max_time","type":"integer","required":false,"default":10,"description":"Max total seconds.","validation":{"min":1,"max":60}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Probe example.com","args":{"url":"https://example.com/"}},{"title":"Probe an internal endpoint with a self-signed cert","args":{"insecure":true,"url":"https://10.0.0.5:8443/healthz"}}],"search_terms":["site down","website unreachable","is the site up","slow website"],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -sS --globoff --proto =http,https \"$@\" -o /dev/null --max-time \"$MAX_TIME\" -w \"http_code=%{http_code}\\nlookup=%{time_namelookup}\\nconnect=%{time_connect}\\nappconnect=%{time_appconnect}\\nstarttransfer=%{time_starttransfer}\\ntotal=%{time_total}\\nsize=%{size_download}\\n\" \"$URL\""]}},{"id":"net.ipinfo_lookup","title":"ipinfo (geo + ASN for an IP)","summary":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","description":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","kind":"exec","risk":"low","side_effects":["One HTTPS query to ipinfo.io.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"Lookup 1.1.1.1","args":{"ip":"1.1.1.1"}}],"search_terms":["who owns this ip"],"command":{"binary":"curl","argv":["-sfL","--globoff","--proto","=https","--proto-redir","=https","--max-time","10","https://ipinfo.io/{{ args.ip }}/json"]}},{"id":"net.ping_extended","title":"ping (with count + timeout)","summary":"Send N ICMP echo requests with explicit per-probe timeout.","description":"Send N ICMP echo requests with explicit per-probe timeout.","kind":"exec","risk":"low","side_effects":["Outbound ICMP.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":10,"description":"Probes.","validation":{"min":1,"max":100}},{"name":"timeout","type":"integer","required":false,"default":2,"description":"Per-probe timeout seconds.","validation":{"min":1,"max":10}}],"examples":[{"title":"10 probes to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-W","{{ args.timeout }}","{{ args.host }}"]}},{"id":"net.tcp_probe","title":"Probe one TCP port","summary":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","description":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","kind":"script","risk":"low","side_effects":["One outbound TCP connection attempt.","Sends no application data and never listens."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP address.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9.:-]{0,251}[A-Za-z0-9])?$","max_length":253}},{"name":"port","type":"integer","required":true,"description":"Target TCP port.","validation":{"min":1,"max":65535}},{"name":"timeout","type":"integer","required":false,"default":3,"description":"Connect timeout in seconds.","validation":{"min":1,"max":30}}],"examples":[{"title":"Probe PostgreSQL from this runner","args":{"host":"database.internal","port":5432,"timeout":3}}],"search_terms":["connection refused","port unreachable","cross-host connectivity"]},{"id":"net.tls_cert_expiry","title":"TLS cert expiry probe","summary":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","description":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}},{"name":"sni","type":"string","required":false,"default":"","description":"SNI override (default = host).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{0,253}$"}}],"examples":[{"title":"Cert for example.com","args":{"host":"example.com"}}],"search_terms":["renewal","certificate error"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername ${SNI:-\"$1\"} </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer","emisar","{{ args.host }}"]}},{"id":"net.tls_chain_dump","title":"TLS chain dump","summary":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","description":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for example.com","args":{"host":"example.com"}}],"search_terms":["missing intermediate"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.host }}"]}},{"id":"net.tls_protocol_check","title":"TLS protocol support check","summary":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","description":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","kind":"exec","risk":"low","side_effects":["Up to 4 outbound TLS handshakes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"TLS support matrix","args":{"host":"example.com"}}],"search_terms":["weak tls"],"command":{"binary":"/bin/sh","argv":["-c","for v in tls1 tls1_1 tls1_2 tls1_3; do printf '%s: ' \"$v\"; openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -$v </dev/null 2>/dev/null | grep -q 'BEGIN CERT' && echo OK || echo FAIL; done","emisar","{{ args.host }}"]}},{"id":"net.traceroute_mtr","title":"mtr report (route + loss statistics)","summary":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report.","description":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report.","kind":"exec","risk":"low","side_effects":["Outbound ICMP/UDP probes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"cycles","type":"integer","required":false,"default":5,"description":"Number of probe cycles.","validation":{"min":1,"max":30}}],"examples":[{"title":"5-cycle mtr to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["packet loss","network path","flaky connection"],"command":{"binary":"mtr","argv":["--report","--report-cycles={{ args.cycles }}","{{ args.host }}"]}},{"id":"net.whois_summary","title":"whois (registrar + expiry)","summary":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","description":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","kind":"exec","risk":"low","side_effects":["One whois query to the registry.","Read-only."],"args":[{"name":"domain","type":"string","required":true,"description":"Domain.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"whois example.com","args":{"domain":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","raw=$(whois \"$1\"); status=$?\nprintf '%s\\n' \"$raw\" | grep -iE 'registrar|registry|domain name|expir|name server|status' | head -30\nif [ \"$status\" -eq 0 ] && [ -n \"$raw\" ] && \\\n   ! printf '%s\\n' \"$raw\" | grep -qiE 'registrar|registry|domain name|expir|name server|status'; then\n  echo \"whois replied but no summary fields matched — raw reply may be a rate-limit or an unusual ccTLD format\" >&2\nfi\nexit $status\n","emisar","{{ args.domain }}"]}}]},{"version":"0.1.14","content_hash":"sha256:0c8236a0cb7576a41e18a4a5e8536f0e6b53c284345bc609c9fe707b97dbb669","tarball_url":"https://registry.emisar.dev/v1/packs/network-tls/0.1.14/0c8236a0cb7576a41e18a4a5e8536f0e6b53c284345bc609c9fe707b97dbb669/pack.tar.gz","actions":[{"id":"net.dig_dnssec","title":"dig +dnssec (DNSSEC validation)","summary":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","description":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","kind":"exec","risk":"low","side_effects":["One DNS query with DO bit set.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"DNSSEC check","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+dnssec","{{ args.name }}"]}},{"id":"net.dig_record","title":"dig (DNS lookup)","summary":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","description":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name to look up.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SRV","PTR","SOA","CAA"]}},{"name":"resolver","type":"string","required":false,"default":"","description":"Resolver IP (empty = system default).","validation":{"pattern":"^[0-9a-fA-F.:]{0,45}$"}}],"examples":[{"title":"A record","args":{"name":"example.com"}},{"title":"MX record via Google's resolver","args":{"name":"example.com","resolver":"8.8.8.8","type":"MX"}}],"search_terms":["resolve hostname","dns not resolving"],"command":{"binary":"/bin/sh","argv":["-c","dig +short {{ args.type }} \"$1\" ${RES:+@$RES}","emisar","{{ args.name }}"]}},{"id":"net.dig_reverse","title":"dig -x (reverse DNS)","summary":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","description":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"PTR for 8.8.8.8","args":{"ip":"8.8.8.8"}}],"search_terms":[],"command":{"binary":"dig","argv":["-x","{{ args.ip }}"]}},{"id":"net.dig_trace","title":"dig +trace (full delegation chain)","summary":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","description":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","kind":"exec","risk":"low","side_effects":["Multiple DNS queries down the delegation tree.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"Trace delegation","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+trace","{{ args.name }}"]}},{"id":"net.http_headers","title":"HTTP response headers (curl -I)","summary":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","description":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","kind":"exec","risk":"low","side_effects":["One curl HEAD request.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Headers for example.com","args":{"url":"https://example.com/"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -sIL --globoff --proto =http,https --proto-redir =http,https \"$@\" --max-time 10 \"$URL\""]}},{"id":"net.http_probe","title":"HTTP probe with timing","summary":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","description":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","kind":"exec","risk":"low","side_effects":["Outbound HTTP(S) to the URL.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL to probe.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"max_time","type":"integer","required":false,"default":10,"description":"Max total seconds.","validation":{"min":1,"max":60}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Probe example.com","args":{"url":"https://example.com/"}},{"title":"Probe an internal endpoint with a self-signed cert","args":{"insecure":true,"url":"https://10.0.0.5:8443/healthz"}}],"search_terms":["site down","website unreachable","is the site up","slow website"],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -sS --globoff --proto =http,https \"$@\" -o /dev/null --max-time \"$MAX_TIME\" -w \"http_code=%{http_code}\\nlookup=%{time_namelookup}\\nconnect=%{time_connect}\\nappconnect=%{time_appconnect}\\nstarttransfer=%{time_starttransfer}\\ntotal=%{time_total}\\nsize=%{size_download}\\n\" \"$URL\""]}},{"id":"net.ipinfo_lookup","title":"ipinfo (geo + ASN for an IP)","summary":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","description":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","kind":"exec","risk":"low","side_effects":["One HTTPS query to ipinfo.io.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"Lookup 1.1.1.1","args":{"ip":"1.1.1.1"}}],"search_terms":["who owns this ip"],"command":{"binary":"curl","argv":["-sfL","--globoff","--proto","=https","--proto-redir","=https","--max-time","10","https://ipinfo.io/{{ args.ip }}/json"]}},{"id":"net.ping_extended","title":"ping (with count + timeout)","summary":"Send N ICMP echo requests with explicit per-probe timeout.","description":"Send N ICMP echo requests with explicit per-probe timeout.","kind":"exec","risk":"low","side_effects":["Outbound ICMP.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":10,"description":"Probes.","validation":{"min":1,"max":100}},{"name":"timeout","type":"integer","required":false,"default":2,"description":"Per-probe timeout seconds.","validation":{"min":1,"max":10}}],"examples":[{"title":"10 probes to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-W","{{ args.timeout }}","{{ args.host }}"]}},{"id":"net.tcp_probe","title":"Probe one TCP port","summary":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","description":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","kind":"script","risk":"low","side_effects":["One outbound TCP connection attempt.","Sends no application data and never listens."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP address.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9.:-]{0,251}[A-Za-z0-9])?$","max_length":253}},{"name":"port","type":"integer","required":true,"description":"Target TCP port.","validation":{"min":1,"max":65535}},{"name":"timeout","type":"integer","required":false,"default":3,"description":"Connect timeout in seconds.","validation":{"min":1,"max":30}}],"examples":[{"title":"Probe PostgreSQL from this runner","args":{"host":"database.internal","port":5432,"timeout":3}}],"search_terms":["connection refused","port unreachable","cross-host connectivity"]},{"id":"net.tls_cert_expiry","title":"TLS cert expiry probe","summary":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","description":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}},{"name":"sni","type":"string","required":false,"default":"","description":"SNI override (default = host).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{0,253}$"}}],"examples":[{"title":"Cert for example.com","args":{"host":"example.com"}}],"search_terms":["renewal","certificate error"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername ${SNI:-\"$1\"} </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer","emisar","{{ args.host }}"]}},{"id":"net.tls_chain_dump","title":"TLS chain dump","summary":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","description":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for example.com","args":{"host":"example.com"}}],"search_terms":["missing intermediate"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.host }}"]}},{"id":"net.tls_protocol_check","title":"TLS protocol support check","summary":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","description":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","kind":"exec","risk":"low","side_effects":["Up to 4 outbound TLS handshakes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"TLS support matrix","args":{"host":"example.com"}}],"search_terms":["weak tls"],"command":{"binary":"/bin/sh","argv":["-c","for v in tls1 tls1_1 tls1_2 tls1_3; do printf '%s: ' \"$v\"; openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -$v </dev/null 2>/dev/null | grep -q 'BEGIN CERT' && echo OK || echo FAIL; done","emisar","{{ args.host }}"]}},{"id":"net.traceroute_mtr","title":"mtr report (route + loss statistics)","summary":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report.","description":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report.","kind":"exec","risk":"low","side_effects":["Outbound ICMP/UDP probes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"cycles","type":"integer","required":false,"default":5,"description":"Number of probe cycles.","validation":{"min":1,"max":30}}],"examples":[{"title":"5-cycle mtr to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["packet loss","network path","flaky connection"],"command":{"binary":"mtr","argv":["--report","--report-cycles={{ args.cycles }}","{{ args.host }}"]}},{"id":"net.whois_summary","title":"whois (registrar + expiry)","summary":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","description":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","kind":"exec","risk":"low","side_effects":["One whois query to the registry.","Read-only."],"args":[{"name":"domain","type":"string","required":true,"description":"Domain.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"whois example.com","args":{"domain":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","raw=$(whois \"$1\"); status=$?\nprintf '%s\\n' \"$raw\" | grep -iE 'registrar|registry|domain name|expir|name server|status' | head -30\nif [ \"$status\" -eq 0 ] && [ -n \"$raw\" ] && \\\n   ! printf '%s\\n' \"$raw\" | grep -qiE 'registrar|registry|domain name|expir|name server|status'; then\n  echo \"whois replied but no summary fields matched — raw reply may be a rate-limit or an unusual ccTLD format\" >&2\nfi\nexit $status\n","emisar","{{ args.domain }}"]}}]},{"version":"0.1.13","content_hash":"sha256:241760dfb2861759041b5d2192167648bb69d357d4b7340b3053d9bdac2b3955","tarball_url":"https://registry.emisar.dev/v1/packs/network-tls/0.1.13/241760dfb2861759041b5d2192167648bb69d357d4b7340b3053d9bdac2b3955/pack.tar.gz","actions":[{"id":"net.dig_dnssec","title":"dig +dnssec (DNSSEC validation)","summary":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","description":"Issue a DNSSEC-validating query. Returns RRSIG records and the AD (authenticated-data) flag if validation succeeded.","kind":"exec","risk":"low","side_effects":["One DNS query with DO bit set.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"DNSSEC check","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+dnssec","{{ args.name }}"]}},{"id":"net.dig_record","title":"dig (DNS lookup)","summary":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","description":"`dig +short <type> <name> @<resolver>` — look up one DNS record. Type defaults to A; specify AAAA, MX, NS, TXT, CNAME, SRV. Resolver defaults to system default.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name to look up.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}},{"name":"type","type":"string","required":false,"default":"A","description":"Record type.","validation":{"enum":["A","AAAA","MX","NS","TXT","CNAME","SRV","PTR","SOA","CAA"]}},{"name":"resolver","type":"string","required":false,"default":"","description":"Resolver IP (empty = system default).","validation":{"pattern":"^[0-9a-fA-F.:]{0,45}$"}}],"examples":[{"title":"A record","args":{"name":"example.com"}},{"title":"MX record via Google's resolver","args":{"name":"example.com","resolver":"8.8.8.8","type":"MX"}}],"search_terms":["resolve hostname","dns not resolving"],"command":{"binary":"/bin/sh","argv":["-c","dig +short {{ args.type }} \"$1\" ${RES:+@$RES}","emisar","{{ args.name }}"]}},{"id":"net.dig_reverse","title":"dig -x (reverse DNS)","summary":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","description":"`dig -x <ip>` — reverse PTR lookup for an IPv4 or IPv6 address.","kind":"exec","risk":"low","side_effects":["One DNS query.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6 address.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"PTR for 8.8.8.8","args":{"ip":"8.8.8.8"}}],"search_terms":[],"command":{"binary":"dig","argv":["-x","{{ args.ip }}"]}},{"id":"net.dig_trace","title":"dig +trace (full delegation chain)","summary":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","description":"`dig +trace` — follow the DNS delegation chain from the root to the authoritative server. Use to debug \"the wrong nameservers are answering.\"","kind":"exec","risk":"low","side_effects":["Multiple DNS queries down the delegation tree.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Domain name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9.\\-_]{0,252}$"}}],"examples":[{"title":"Trace delegation","args":{"name":"example.com"}}],"search_terms":[],"command":{"binary":"dig","argv":["+trace","{{ args.name }}"]}},{"id":"net.http_headers","title":"HTTP response headers (curl -I)","summary":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","description":"Dump response headers from a URL, following redirects. Use to confirm cache-control / hsts / set-cookie / cors setup. Set insecure=true to skip TLS verification for an internal or self-signed certificate.","kind":"exec","risk":"low","side_effects":["One curl HEAD request.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Headers for example.com","args":{"url":"https://example.com/"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -sIL --globoff --proto =http,https --proto-redir =http,https \"$@\" --max-time 10 \"$URL\""]}},{"id":"net.http_probe","title":"HTTP probe with timing","summary":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","description":"Probe a URL with curl, returning HTTP status, DNS / TCP / TLS / total timings, and bytes transferred. Use as a synthetic check. Set insecure=true to skip TLS verification when the endpoint serves an internal or self-signed certificate (otherwise such a probe reports http_code=000).","kind":"exec","risk":"low","side_effects":["Outbound HTTP(S) to the URL.","Read-only."],"args":[{"name":"url","type":"string","required":true,"description":"URL to probe.","validation":{"pattern":"^https?://[a-zA-Z0-9.:/_\\-?=&%+]{1,512}$"}},{"name":"max_time","type":"integer","required":false,"default":10,"description":"Max total seconds.","validation":{"min":1,"max":60}},{"name":"insecure","type":"boolean","required":false,"default":false,"description":"Skip TLS certificate verification (curl -k). Use for internal or self-signed certs."}],"examples":[{"title":"Probe example.com","args":{"url":"https://example.com/"}},{"title":"Probe an internal endpoint with a self-signed cert","args":{"insecure":true,"url":"https://10.0.0.5:8443/healthz"}}],"search_terms":["site down","website unreachable","is the site up","slow website"],"command":{"binary":"/bin/sh","argv":["-c","set --; [ \"$INSECURE\" = \"true\" ] && set -- -k; exec curl -sS --globoff --proto =http,https \"$@\" -o /dev/null --max-time \"$MAX_TIME\" -w \"http_code=%{http_code}\\nlookup=%{time_namelookup}\\nconnect=%{time_connect}\\nappconnect=%{time_appconnect}\\nstarttransfer=%{time_starttransfer}\\ntotal=%{time_total}\\nsize=%{size_download}\\n\" \"$URL\""]}},{"id":"net.ipinfo_lookup","title":"ipinfo (geo + ASN for an IP)","summary":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","description":"Look up an IP at ipinfo.io. Returns city/region/country/org/asn. Outbound HTTP to ipinfo.io required.","kind":"exec","risk":"low","side_effects":["One HTTPS query to ipinfo.io.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"IPv4 or IPv6.","validation":{"pattern":"^[0-9a-fA-F.:]{1,45}$"}}],"examples":[{"title":"Lookup 1.1.1.1","args":{"ip":"1.1.1.1"}}],"search_terms":["who owns this ip"],"command":{"binary":"curl","argv":["-sfL","--globoff","--proto","=https","--proto-redir","=https","--max-time","10","https://ipinfo.io/{{ args.ip }}/json"]}},{"id":"net.ping_extended","title":"ping (with count + timeout)","summary":"Send N ICMP echo requests with explicit per-probe timeout.","description":"Send N ICMP echo requests with explicit per-probe timeout.","kind":"exec","risk":"low","side_effects":["Outbound ICMP.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"count","type":"integer","required":false,"default":10,"description":"Probes.","validation":{"min":1,"max":100}},{"name":"timeout","type":"integer","required":false,"default":2,"description":"Per-probe timeout seconds.","validation":{"min":1,"max":10}}],"examples":[{"title":"10 probes to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["unreachable"],"command":{"binary":"ping","argv":["-c","{{ args.count }}","-W","{{ args.timeout }}","{{ args.host }}"]}},{"id":"net.tcp_probe","title":"Probe one TCP port","summary":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","description":"Attempt one bounded TCP connection from the runner to a host and port. A successful handshake proves TCP reachability only; it does not validate an application protocol, TLS, authentication, or service health.","kind":"script","risk":"low","side_effects":["One outbound TCP connection attempt.","Sends no application data and never listens."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP address.","validation":{"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9.:-]{0,251}[A-Za-z0-9])?$","max_length":253}},{"name":"port","type":"integer","required":true,"description":"Target TCP port.","validation":{"min":1,"max":65535}},{"name":"timeout","type":"integer","required":false,"default":3,"description":"Connect timeout in seconds.","validation":{"min":1,"max":30}}],"examples":[{"title":"Probe PostgreSQL from this runner","args":{"host":"database.internal","port":5432,"timeout":3}}],"search_terms":["connection refused","port unreachable","cross-host connectivity"]},{"id":"net.tls_cert_expiry","title":"TLS cert expiry probe","summary":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","description":"Connect to host:port with SNI and dump cert subject, issuer, notBefore, notAfter. Use for \"when does this cert expire?\" alerts.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}},{"name":"sni","type":"string","required":false,"default":"","description":"SNI override (default = host).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{0,253}$"}}],"examples":[{"title":"Cert for example.com","args":{"host":"example.com"}}],"search_terms":["renewal","certificate error"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername ${SNI:-\"$1\"} </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer","emisar","{{ args.host }}"]}},{"id":"net.tls_chain_dump","title":"TLS chain dump","summary":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","description":"Dump the full certificate chain a server returns. Use to debug \"browsers see incomplete chain\" errors.","kind":"exec","risk":"low","side_effects":["One openssl s_client connection.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for example.com","args":{"host":"example.com"}}],"search_terms":["missing intermediate"],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.host }}"]}},{"id":"net.tls_protocol_check","title":"TLS protocol support check","summary":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","description":"Probe TLS 1.0/1.1/1.2/1.3 support on host:port one at a time, reporting which versions the server accepts. Use for compliance audits (\"is TLS 1.0 still on?\"). Runs with OPENSSL_CONF=/dev/null so the host's system MinProtocol floor (TLSv1.2 on Debian) doesn't pre-fail the 1.0/1.1 probes — each result reflects the server, not the client.","kind":"exec","risk":"low","side_effects":["Up to 4 outbound TLS handshakes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Host.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port.","validation":{"min":1,"max":65535}}],"examples":[{"title":"TLS support matrix","args":{"host":"example.com"}}],"search_terms":["weak tls"],"command":{"binary":"/bin/sh","argv":["-c","for v in tls1 tls1_1 tls1_2 tls1_3; do printf '%s: ' \"$v\"; openssl s_client -connect \"$1\":{{ args.port }} -servername \"$1\" -$v </dev/null 2>/dev/null | grep -q 'BEGIN CERT' && echo OK || echo FAIL; done","emisar","{{ args.host }}"]}},{"id":"net.traceroute_mtr","title":"mtr report (route + loss statistics)","summary":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report.","description":"`mtr --report` — 5 cycles of traceroute with per-hop packet loss and latency. The combined traceroute + ping report.","kind":"exec","risk":"low","side_effects":["Outbound ICMP/UDP probes.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target hostname or IP.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"cycles","type":"integer","required":false,"default":5,"description":"Number of probe cycles.","validation":{"min":1,"max":30}}],"examples":[{"title":"5-cycle mtr to 1.1.1.1","args":{"host":"1.1.1.1"}}],"search_terms":["packet loss","network path","flaky connection"],"command":{"binary":"mtr","argv":["--report","--report-cycles={{ args.cycles }}","{{ args.host }}"]}},{"id":"net.whois_summary","title":"whois (registrar + expiry)","summary":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","description":"Show filtered whois output — registrar, dates, name servers. Use to check \"is this domain about to expire?\"","kind":"exec","risk":"low","side_effects":["One whois query to the registry.","Read-only."],"args":[{"name":"domain","type":"string","required":true,"description":"Domain.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,252}$"}}],"examples":[{"title":"whois example.com","args":{"domain":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","raw=$(whois \"$1\"); status=$?\nprintf '%s\\n' \"$raw\" | grep -iE 'registrar|registry|domain name|expir|name server|status' | head -30\nif [ \"$status\" -eq 0 ] && [ -n \"$raw\" ] && \\\n   ! printf '%s\\n' \"$raw\" | grep -qiE 'registrar|registry|domain name|expir|name server|status'; then\n  echo \"whois replied but no summary fields matched — raw reply may be a rate-limit or an unusual ccTLD format\" >&2\nfi\nexit $status\n","emisar","{{ args.domain }}"]}}]}]},{"id":"nfs","name":"NFS server + client","version":"0.1.9","description":"Inspect a host's NFS exports, mounted shares, RPC state, active client connections. Plus two narrow operator actions: exportfs -r (re-export) and exportfs -u (unexport one client:path — evicts that client). Read-only otherwise.","vendor":"emisar","homepage":"https://emisar.dev/packs/nfs","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/nfs","content_hash":"sha256:53c05c651cf27abbf7267601d4dea9a8698486d4acbb78437af03a6dc7f62d63","tarball_url":"https://registry.emisar.dev/v1/packs/nfs/0.1.9/53c05c651cf27abbf7267601d4dea9a8698486d4acbb78437af03a6dc7f62d63/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":["nfsd"],"ports":[2049]},"setup":{"summary":"Inspects the local runner host's NFS server/client state — no credentials needed.","notes":["showmount, nfsstat, rpcinfo, the kernel mount inventory, and the exported-table file read work without elevated host access."],"host_access":[{"actions":["nfs.exportfs_v","nfs.exportfs_r","nfs.exportfs_unexport_path"],"requirement":"Read and change the kernel NFS export table as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-nfs-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Export actions can expose or withdraw host filesystems from NFS clients."}]}],"verify":"nfs.exportfs_v"},"actions":[{"id":"nfs.cat_etab","title":"cat /var/lib/nfs/etab","summary":"Show the effective export table (what kernel actually serves).","description":"Show the effective export table (what kernel actually serves).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Effective exports","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/nfs/etab"]}},{"id":"nfs.exportfs_r","title":"exportfs -r","summary":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","description":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","kind":"exec","risk":"high","side_effects":["Existing exports table is re-synced from /etc/exports.","Brief stall possible on existing NFS clients."],"args":[],"examples":[{"title":"Re-export","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-r"]}},{"id":"nfs.exportfs_unexport_path","title":"exportfs -u <client>:<path>","summary":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","description":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","kind":"exec","risk":"high","side_effects":["Named client can no longer mount the path.","Active mounts return ESTALE for new operations.","Other clients unaffected."],"args":[{"name":"client","type":"string","required":true,"description":"Client hostname, IP, or CIDR.","validation":{"pattern":"^[a-zA-Z0-9._:\\-/]{1,128}$"}},{"name":"path","type":"string","required":true,"description":"Export path.","validation":{"pattern":"^(/[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*)+$","max_length":512}}],"examples":[{"title":"Evict a noisy client","args":{"client":"10.1.2.3","path":"/exports/data"}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-u","{{ args.client }}:{{ args.path }}"]}},{"id":"nfs.exportfs_v","title":"exportfs -v","summary":"List currently-exported NFS shares + options.","description":"List currently-exported NFS shares + options.","kind":"exec","risk":"low","side_effects":["One exportfs call.","Read-only."],"args":[],"examples":[{"title":"Active exports","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-v"]}},{"id":"nfs.nfs_mounts","title":"NFS mounts on this host","summary":"List all NFS-typed mounts currently visible.","description":"List all NFS-typed mounts currently visible.","kind":"exec","risk":"low","side_effects":["One mount table read.","Read-only."],"args":[],"examples":[{"title":"NFS mounts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mount -t nfs,nfs4 -l"]}},{"id":"nfs.nfsstat_c","title":"nfsstat -c (client)","summary":"Show client-side RPC + NFS op counts.","description":"Show client-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Client stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-c"]}},{"id":"nfs.nfsstat_s","title":"nfsstat -s (server)","summary":"Show server-side RPC + NFS op counts.","description":"Show server-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Server stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-s"]}},{"id":"nfs.rpcinfo_p","title":"rpcinfo -p","summary":"List RPC services registered with rpcbind.","description":"List RPC services registered with rpcbind.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"RPC services","args":{}}],"search_terms":[],"command":{"binary":"rpcinfo","argv":["-p"]}},{"id":"nfs.showmount_e","title":"showmount -e","summary":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","description":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"Discoverable exports","args":{}}],"search_terms":[],"command":{"binary":"showmount","argv":["-e","127.0.0.1"]}}],"previous_versions":[{"version":"0.1.8","content_hash":"sha256:56f8dabe083a18aa473bf16f35f1b33af4f575102b267d3c9dba5e01b826ea54","tarball_url":"https://registry.emisar.dev/v1/packs/nfs/0.1.8/56f8dabe083a18aa473bf16f35f1b33af4f575102b267d3c9dba5e01b826ea54/pack.tar.gz","actions":[{"id":"nfs.cat_etab","title":"cat /var/lib/nfs/etab","summary":"Show the effective export table (what kernel actually serves).","description":"Show the effective export table (what kernel actually serves).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Effective exports","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/nfs/etab"]}},{"id":"nfs.exportfs_r","title":"exportfs -r","summary":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","description":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","kind":"exec","risk":"high","side_effects":["Existing exports table is re-synced from /etc/exports.","Brief stall possible on existing NFS clients."],"args":[],"examples":[{"title":"Re-export","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-r"]}},{"id":"nfs.exportfs_unexport_path","title":"exportfs -u <client>:<path>","summary":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","description":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","kind":"exec","risk":"high","side_effects":["Named client can no longer mount the path.","Active mounts return ESTALE for new operations.","Other clients unaffected."],"args":[{"name":"client","type":"string","required":true,"description":"Client hostname, IP, or CIDR.","validation":{"pattern":"^[a-zA-Z0-9._:\\-/]{1,128}$"}},{"name":"path","type":"string","required":true,"description":"Export path.","validation":{"pattern":"^(/[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*)+$","max_length":512}}],"examples":[{"title":"Evict a noisy client","args":{"client":"10.1.2.3","path":"/exports/data"}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-u","{{ args.client }}:{{ args.path }}"]}},{"id":"nfs.exportfs_v","title":"exportfs -v","summary":"List currently-exported NFS shares + options.","description":"List currently-exported NFS shares + options.","kind":"exec","risk":"low","side_effects":["One exportfs call.","Read-only."],"args":[],"examples":[{"title":"Active exports","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-v"]}},{"id":"nfs.nfs_mounts","title":"NFS mounts on this host","summary":"List all NFS-typed mounts currently visible.","description":"List all NFS-typed mounts currently visible.","kind":"exec","risk":"low","side_effects":["One mount table read.","Read-only."],"args":[],"examples":[{"title":"NFS mounts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mount -t nfs,nfs4 -l"]}},{"id":"nfs.nfsstat_c","title":"nfsstat -c (client)","summary":"Show client-side RPC + NFS op counts.","description":"Show client-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Client stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-c"]}},{"id":"nfs.nfsstat_s","title":"nfsstat -s (server)","summary":"Show server-side RPC + NFS op counts.","description":"Show server-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Server stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-s"]}},{"id":"nfs.rpcinfo_p","title":"rpcinfo -p","summary":"List RPC services registered with rpcbind.","description":"List RPC services registered with rpcbind.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"RPC services","args":{}}],"search_terms":[],"command":{"binary":"rpcinfo","argv":["-p"]}},{"id":"nfs.showmount_e","title":"showmount -e","summary":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","description":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"Discoverable exports","args":{}}],"search_terms":[],"command":{"binary":"showmount","argv":["-e","127.0.0.1"]}}]},{"version":"0.1.7","content_hash":"sha256:8e38c10b5b77baae98cf73418cb15c6a1c3e3e4f82f726edbec0c8a08969188b","tarball_url":"https://registry.emisar.dev/v1/packs/nfs/0.1.7/8e38c10b5b77baae98cf73418cb15c6a1c3e3e4f82f726edbec0c8a08969188b/pack.tar.gz","actions":[{"id":"nfs.cat_etab","title":"cat /var/lib/nfs/etab","summary":"Show the effective export table (what kernel actually serves).","description":"Show the effective export table (what kernel actually serves).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Effective exports","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/nfs/etab"]}},{"id":"nfs.exportfs_r","title":"exportfs -r","summary":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","description":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","kind":"exec","risk":"high","side_effects":["Existing exports table is re-synced from /etc/exports.","Brief stall possible on existing NFS clients."],"args":[],"examples":[{"title":"Re-export","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-r"]}},{"id":"nfs.exportfs_unexport_path","title":"exportfs -u <client>:<path>","summary":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","description":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","kind":"exec","risk":"high","side_effects":["Named client can no longer mount the path.","Active mounts return ESTALE for new operations.","Other clients unaffected."],"args":[{"name":"client","type":"string","required":true,"description":"Client hostname, IP, or CIDR.","validation":{"pattern":"^[a-zA-Z0-9._:\\-/]{1,128}$"}},{"name":"path","type":"string","required":true,"description":"Export path.","validation":{"pattern":"^(/[A-Za-z0-9_.-]*[A-Za-z0-9_-][A-Za-z0-9_.-]*)+$","max_length":512}}],"examples":[{"title":"Evict a noisy client","args":{"client":"10.1.2.3","path":"/exports/data"}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-u","{{ args.client }}:{{ args.path }}"]}},{"id":"nfs.exportfs_v","title":"exportfs -v","summary":"List currently-exported NFS shares + options.","description":"List currently-exported NFS shares + options.","kind":"exec","risk":"low","side_effects":["One exportfs call.","Read-only."],"args":[],"examples":[{"title":"Active exports","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-v"]}},{"id":"nfs.nfs_mounts","title":"NFS mounts on this host","summary":"List all NFS-typed mounts currently visible.","description":"List all NFS-typed mounts currently visible.","kind":"exec","risk":"low","side_effects":["One mount table read.","Read-only."],"args":[],"examples":[{"title":"NFS mounts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mount -t nfs,nfs4 -l"]}},{"id":"nfs.nfsstat_c","title":"nfsstat -c (client)","summary":"Show client-side RPC + NFS op counts.","description":"Show client-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Client stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-c"]}},{"id":"nfs.nfsstat_s","title":"nfsstat -s (server)","summary":"Show server-side RPC + NFS op counts.","description":"Show server-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Server stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-s"]}},{"id":"nfs.rpcinfo_p","title":"rpcinfo -p","summary":"List RPC services registered with rpcbind.","description":"List RPC services registered with rpcbind.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"RPC services","args":{}}],"search_terms":[],"command":{"binary":"rpcinfo","argv":["-p"]}},{"id":"nfs.showmount_e","title":"showmount -e","summary":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","description":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"Discoverable exports","args":{}}],"search_terms":[],"command":{"binary":"showmount","argv":["-e","127.0.0.1"]}}]},{"version":"0.1.6","content_hash":"sha256:fbc1087bba7743eb9c5ec4a17b3d4ebc43583fb620d10323753d0a9ca61007ea","tarball_url":"https://registry.emisar.dev/v1/packs/nfs/0.1.6/fbc1087bba7743eb9c5ec4a17b3d4ebc43583fb620d10323753d0a9ca61007ea/pack.tar.gz","actions":[{"id":"nfs.cat_etab","title":"cat /var/lib/nfs/etab","summary":"Show the effective export table (what kernel actually serves).","description":"Show the effective export table (what kernel actually serves).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Effective exports","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/var/lib/nfs/etab"]}},{"id":"nfs.exportfs_r","title":"exportfs -r","summary":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","description":"Re-export everything in /etc/exports. New mounts work; established clients may stall briefly.","kind":"exec","risk":"high","side_effects":["Existing exports table is re-synced from /etc/exports.","Brief stall possible on existing NFS clients."],"args":[],"examples":[{"title":"Re-export","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-r"]}},{"id":"nfs.exportfs_unexport_path","title":"exportfs -u <client>:<path>","summary":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","description":"Stop exporting one path to one client. Active mounts on that client start failing operations. Use to evict a misbehaving client without restarting the NFS server.","kind":"exec","risk":"high","side_effects":["Named client can no longer mount the path.","Active mounts return ESTALE for new operations.","Other clients unaffected."],"args":[{"name":"client","type":"string","required":true,"description":"Client hostname, IP, or CIDR.","validation":{"pattern":"^[a-zA-Z0-9._:\\-/]{1,128}$"}},{"name":"path","type":"string","required":true,"description":"Export path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$"}}],"examples":[{"title":"Evict a noisy client","args":{"client":"10.1.2.3","path":"/exports/data"}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-u","{{ args.client }}:{{ args.path }}"]}},{"id":"nfs.exportfs_v","title":"exportfs -v","summary":"List currently-exported NFS shares + options.","description":"List currently-exported NFS shares + options.","kind":"exec","risk":"low","side_effects":["One exportfs call.","Read-only."],"args":[],"examples":[{"title":"Active exports","args":{}}],"search_terms":[],"command":{"binary":"exportfs","argv":["-v"]}},{"id":"nfs.nfs_mounts","title":"NFS mounts on this host","summary":"List all NFS-typed mounts currently visible.","description":"List all NFS-typed mounts currently visible.","kind":"exec","risk":"low","side_effects":["One mount table read.","Read-only."],"args":[],"examples":[{"title":"NFS mounts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","mount -t nfs,nfs4 -l"]}},{"id":"nfs.nfsstat_c","title":"nfsstat -c (client)","summary":"Show client-side RPC + NFS op counts.","description":"Show client-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Client stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-c"]}},{"id":"nfs.nfsstat_s","title":"nfsstat -s (server)","summary":"Show server-side RPC + NFS op counts.","description":"Show server-side RPC + NFS op counts.","kind":"exec","risk":"low","side_effects":["One nfsstat call.","Read-only."],"args":[],"examples":[{"title":"Server stats","args":{}}],"search_terms":[],"command":{"binary":"nfsstat","argv":["-s"]}},{"id":"nfs.rpcinfo_p","title":"rpcinfo -p","summary":"List RPC services registered with rpcbind.","description":"List RPC services registered with rpcbind.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"RPC services","args":{}}],"search_terms":[],"command":{"binary":"rpcinfo","argv":["-p"]}},{"id":"nfs.showmount_e","title":"showmount -e","summary":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","description":"List exports as seen via rpcbind (what NFS clients discover). On NFSv4-only hosts (no mountd/rpcbind) it returns \"RPC: Program not registered\" — use nfs.exportfs_v for the authoritative export list there.","kind":"exec","risk":"low","side_effects":["One rpcbind query.","Read-only."],"args":[],"examples":[{"title":"Discoverable exports","args":{}}],"search_terms":[],"command":{"binary":"showmount","argv":["-e","127.0.0.1"]}}]}]},{"id":"nginx","name":"Nginx operations pack","version":"0.2.24","description":"Operator pack for nginx — read-only status + access-log analysis, TLS cert probes, and narrow operator actions (test_config, reload, graceful quit, stop). Full restart is intentionally not included; use systemd for that.","vendor":"emisar","homepage":"https://emisar.dev/packs/nginx","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/nginx","content_hash":"sha256:02ea5e76859006b0ebccde310aa93576ce43b165770d90dccba845979e77fc71","tarball_url":"https://registry.emisar.dev/v1/packs/nginx/0.2.24/02ea5e76859006b0ebccde310aa93576ce43b165770d90dccba845979e77fc71/pack.tar.gz","requires":{"os":["linux"],"binaries":["nginx","curl"]},"detect":{"binaries":[],"processes":["nginx"],"ports":[]},"setup":{"summary":"Operates on the local nginx instance on the runner host — no credentials needed. Status actions curl the stub_status endpoint at 127.0.0.1; config and signal actions run the nginx binary directly.","env":[{"name":"NGINX_ACCESS_LOG","description":"Where this host's nginx access log lives, for the access-log actions. Set it when the log is outside `/var/log/nginx` — the actions' own log_path argument is deliberately contained to that directory, so this is how the host administrator, rather than a caller, declares a non-standard location.","default":"/var/log/nginx/access.log","example":"/data/logs/nginx/access.log"},{"name":"NGINX_ERROR_LOG","description":"Where this host's nginx error log lives, for error_tail. Same reasoning as `NGINX_ACCESS_LOG`.","default":"/var/log/nginx/error.log","example":"/data/logs/nginx/error.log"}],"notes":["Status actions require `stub_status on;` in a location reachable from 127.0.0.1; the `url` arg is loopback-only (127.0.0.1/localhost/[::1]) — pass a non-default port/path, not an off-host target.","Logs outside `/var/log/nginx`: set `NGINX_ACCESS_LOG` / `NGINX_ERROR_LOG` (and allowlist them in the runner's `execution.inherit_env`). The log_path argument stays contained to `/var/log/nginx` because a caller — including an LLM — supplies it; the environment is host-administrator state, and anyone who can set it can already read the file. The official container image symlinks access.log to stdout, in which case no file exists to read at any path and the host's log collector owns it. For unrestricted `/var/log` access, install linux-core, whose name says so."],"host_access":[{"actions":["nginx.config_dump","nginx.vhost_list","nginx.upstream_list","nginx.test_config","nginx.reload","nginx.quit_graceful","nginx.stop_immediate"],"requirement":"Read protected Nginx configuration or signal its root-owned master.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-nginx-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Nginx actions can expose private configuration and can stop or reload the web server."}]},{"actions":["nginx.access_top_urls","nginx.access_top_clients","nginx.log_grep_5xx","nginx.log_grep_4xx","nginx.slow_requests","nginx.bytes_by_url","nginx.error_tail"],"requirement":"Read Nginx logs through the Debian or Ubuntu system log-reader group.","recipes":[{"name":"Add the Emisar service user to adm","commands":["sudo usermod -aG adm emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx adm","sudo -u emisar test -r /var/log/nginx/error.log"],"impact":"Every process running as emisar can read every host log granted to adm, not only Nginx logs. RHEL-family paths need an equivalent persistent log-reader grant."}]}],"verify":"nginx.active_version"},"actions":[{"id":"nginx.access_top_clients","title":"Top client IPs from access log","summary":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","description":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N IPs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 source IPs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.access_top_urls","title":"Top URLs from access log","summary":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","description":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 URLs from last 100k lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.active_version","title":"Active nginx version + build","summary":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","description":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"nginx -V","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-V"]}},{"id":"nginx.bytes_by_url","title":"Top URLs by total bytes sent","summary":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","description":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top URLs by traffic","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{bytes[$7]+=$10} END{for(u in bytes) printf \"%d %s\\n\", bytes[u], u}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.compiled_modules","title":"Compiled-in nginx modules","summary":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","description":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"Module list","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nginx -V 2>&1 | tr ' ' '\\n' | grep -E '^--(with|add)'"]}},{"id":"nginx.config_dump","title":"Full loaded config (nginx -T)","summary":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"Show what nginx loaded","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1); status=$?\nprintf '%s\\n' \"$dump\" | head -800\nexit $status\n"]}},{"id":"nginx.connections_now","title":"Active connections (stub_status)","summary":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","description":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Live conn counts","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.error_tail","title":"Tail nginx error log","summary":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","description":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /var/log/nginx/error.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Path to error log. Omit to use $NGINX_ERROR_LOG, else /var/log/nginx/error.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ERROR_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 200 error log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ERROR_LOG:-/var/log/nginx/error.log}\"\n[ -r \"$log\" ] || { echo \"error log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\"\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 4[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 5[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.master_pid","title":"nginx master PID","summary":"Read /run/nginx.pid (or the configured pid path). Read-only.","description":"Read /run/nginx.pid (or the configured pid path). Read-only.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Get the master PID","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/run/nginx.pid"]}},{"id":"nginx.quit_graceful","title":"nginx graceful quit","summary":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","description":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","kind":"exec","risk":"high","side_effects":["Workers stop accepting new connections.","In-flight requests complete; workers exit when done."],"args":[],"examples":[{"title":"Drain + exit","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","quit"]}},{"id":"nginx.reload","title":"nginx reload","summary":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","description":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","kind":"exec","risk":"high","side_effects":["Master spawns new workers.","Old workers drain in-flight requests then exit.","Listen-socket changes (new ports, removed ports) take effect."],"args":[],"examples":[{"title":"Reload config after editing","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","reload"]}},{"id":"nginx.slow_requests","title":"Slowest requests (last N lines)","summary":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","description":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N slowest to return.","validation":{"min":1,"max":200}},{"name":"column","type":"integer","required":false,"default":11,"description":"Column number containing $request_time.","validation":{"min":1,"max":50}}],"examples":[{"title":"30 slowest requests","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk -v c={{ args.column }} '{print $c, $0}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.ssl_cert_expiry","title":"TLS cert expiry for one vhost","summary":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","description":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"Server Name Indication (the vhost to probe).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Expiry for example.com vhost","args":{"sni":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","chain=$(openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" </dev/null 2>&1) || {\n  printf '%s\\n' \"$chain\" >&2\n  exit 1\n}\nprintf '%s\\n' \"$chain\" | openssl x509 -noout -dates -subject -issuer\n","emisar","{{ args.sni }}"]}},{"id":"nginx.ssl_chain_check","title":"TLS chain dump for one vhost","summary":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","description":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"SNI to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for api.example.com","args":{"sni":"api.example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.sni }}"]}},{"id":"nginx.status","title":"Nginx stub_status","summary":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","description":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL on the runner host. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Stub_status from default URL","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.stop_immediate","title":"nginx stop (immediate)","summary":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","description":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","kind":"exec","risk":"critical","side_effects":["Workers SIGTERM immediately.","In-flight requests dropped."],"args":[],"examples":[{"title":"Force-stop nginx","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","stop"]}},{"id":"nginx.test_config","title":"nginx -t","summary":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","description":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","kind":"exec","risk":"low","side_effects":["One nginx -t invocation.","Opens files referenced in the config (logs, modules).","Does NOT change runtime state."],"args":[],"examples":[{"title":"Validate nginx config","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-t"]}},{"id":"nginx.upstream_list","title":"List configured upstream blocks","summary":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","description":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"All upstreams","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | awk '/upstream /{p=1; print; next} p && /\\}/{p=0; print; next} p'\n"]}},{"id":"nginx.vhost_list","title":"List configured server_name + listen blocks","summary":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","description":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation (config validation).","Read-only."],"args":[],"examples":[{"title":"All configured vhosts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | grep -E '^\\s*(server_name|listen)\\b'\n"]}},{"id":"nginx.worker_count","title":"Live worker process count","summary":"Count the workers spawned by the master via pgrep. Read-only.","description":"Count the workers spawned by the master via pgrep. Read-only.","kind":"exec","risk":"low","side_effects":["One pgrep invocation.","Read-only."],"args":[],"examples":[{"title":"Worker count","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","MP=$(cat /run/nginx.pid 2>/dev/null); [ -n \"$MP\" ] || { echo 'cannot read the nginx master pid from /run/nginx.pid' >&2; exit 1; }; count=$(pgrep -c -P \"$MP\"); echo \"${count:-0}\""]}}],"previous_versions":[{"version":"0.2.20","content_hash":"sha256:621eec939bbf368e72b2125f22c864c8d7698a6b5387a512d075ccec82c9be53","tarball_url":"https://registry.emisar.dev/v1/packs/nginx/0.2.20/621eec939bbf368e72b2125f22c864c8d7698a6b5387a512d075ccec82c9be53/pack.tar.gz","actions":[{"id":"nginx.access_top_clients","title":"Top client IPs from access log","summary":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","description":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N IPs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 source IPs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.access_top_urls","title":"Top URLs from access log","summary":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","description":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 URLs from last 100k lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.active_version","title":"Active nginx version + build","summary":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","description":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"nginx -V","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-V"]}},{"id":"nginx.bytes_by_url","title":"Top URLs by total bytes sent","summary":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","description":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top URLs by traffic","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{bytes[$7]+=$10} END{for(u in bytes) printf \"%d %s\\n\", bytes[u], u}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.compiled_modules","title":"Compiled-in nginx modules","summary":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","description":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"Module list","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nginx -V 2>&1 | tr ' ' '\\n' | grep -E '^--(with|add)'"]}},{"id":"nginx.config_dump","title":"Full loaded config (nginx -T)","summary":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"Show what nginx loaded","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1); status=$?\nprintf '%s\\n' \"$dump\" | head -800\nexit $status\n"]}},{"id":"nginx.connections_now","title":"Active connections (stub_status)","summary":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","description":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Live conn counts","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.error_tail","title":"Tail nginx error log","summary":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","description":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/error.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Path to error log. Omit to use $NGINX_ERROR_LOG, else /var/log/nginx/error.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ERROR_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 200 error log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ERROR_LOG:-/var/log/nginx/error.log}\"\n[ -r \"$log\" ] || { echo \"error log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\"\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 4[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 5[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.master_pid","title":"nginx master PID","summary":"Read /run/nginx.pid (or the configured pid path). Read-only.","description":"Read /run/nginx.pid (or the configured pid path). Read-only.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Get the master PID","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/run/nginx.pid"]}},{"id":"nginx.quit_graceful","title":"nginx graceful quit","summary":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","description":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","kind":"exec","risk":"high","side_effects":["Workers stop accepting new connections.","In-flight requests complete; workers exit when done."],"args":[],"examples":[{"title":"Drain + exit","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","quit"]}},{"id":"nginx.reload","title":"nginx reload","summary":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","description":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","kind":"exec","risk":"high","side_effects":["Master spawns new workers.","Old workers drain in-flight requests then exit.","Listen-socket changes (new ports, removed ports) take effect."],"args":[],"examples":[{"title":"Reload config after editing","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","reload"]}},{"id":"nginx.slow_requests","title":"Slowest requests (last N lines)","summary":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","description":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N slowest to return.","validation":{"min":1,"max":200}},{"name":"column","type":"integer","required":false,"default":11,"description":"Column number containing $request_time.","validation":{"min":1,"max":50}}],"examples":[{"title":"30 slowest requests","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk -v c={{ args.column }} '{print $c, $0}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.ssl_cert_expiry","title":"TLS cert expiry for one vhost","summary":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","description":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"Server Name Indication (the vhost to probe).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Expiry for example.com vhost","args":{"sni":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","chain=$(openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" </dev/null 2>&1) || {\n  printf '%s\\n' \"$chain\" >&2\n  exit 1\n}\nprintf '%s\\n' \"$chain\" | openssl x509 -noout -dates -subject -issuer\n","emisar","{{ args.sni }}"]}},{"id":"nginx.ssl_chain_check","title":"TLS chain dump for one vhost","summary":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","description":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"SNI to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for api.example.com","args":{"sni":"api.example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.sni }}"]}},{"id":"nginx.status","title":"Nginx stub_status","summary":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","description":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL on the runner host. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Stub_status from default URL","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.stop_immediate","title":"nginx stop (immediate)","summary":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","description":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","kind":"exec","risk":"critical","side_effects":["Workers SIGTERM immediately.","In-flight requests dropped."],"args":[],"examples":[{"title":"Force-stop nginx","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","stop"]}},{"id":"nginx.test_config","title":"nginx -t","summary":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","description":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","kind":"exec","risk":"low","side_effects":["One nginx -t invocation.","Opens files referenced in the config (logs, modules).","Does NOT change runtime state."],"args":[],"examples":[{"title":"Validate nginx config","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-t"]}},{"id":"nginx.upstream_list","title":"List configured upstream blocks","summary":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","description":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"All upstreams","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | awk '/upstream /{p=1; print; next} p && /\\}/{p=0; print; next} p'\n"]}},{"id":"nginx.vhost_list","title":"List configured server_name + listen blocks","summary":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","description":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation (config validation).","Read-only."],"args":[],"examples":[{"title":"All configured vhosts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | grep -E '^\\s*(server_name|listen)\\b'\n"]}},{"id":"nginx.worker_count","title":"Live worker process count","summary":"Count the workers spawned by the master via pgrep. Read-only.","description":"Count the workers spawned by the master via pgrep. Read-only.","kind":"exec","risk":"low","side_effects":["One pgrep invocation.","Read-only."],"args":[],"examples":[{"title":"Worker count","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","MP=$(cat /run/nginx.pid 2>/dev/null); [ -n \"$MP\" ] && pgrep -c -P \"$MP\" || echo 0"]}}]},{"version":"0.2.17","content_hash":"sha256:00b6e29820cbdccac18fa2f32893a902d6002f2df4f68f784bea880a6975a724","tarball_url":"https://registry.emisar.dev/v1/packs/nginx/0.2.17/00b6e29820cbdccac18fa2f32893a902d6002f2df4f68f784bea880a6975a724/pack.tar.gz","actions":[{"id":"nginx.access_top_clients","title":"Top client IPs from access log","summary":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","description":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N IPs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 source IPs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.access_top_urls","title":"Top URLs from access log","summary":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","description":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 URLs from last 100k lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.active_version","title":"Active nginx version + build","summary":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","description":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"nginx -V","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-V"]}},{"id":"nginx.bytes_by_url","title":"Top URLs by total bytes sent","summary":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","description":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top URLs by traffic","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{bytes[$7]+=$10} END{for(u in bytes) printf \"%d %s\\n\", bytes[u], u}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.compiled_modules","title":"Compiled-in nginx modules","summary":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","description":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"Module list","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nginx -V 2>&1 | tr ' ' '\\n' | grep -E '^--(with|add)'"]}},{"id":"nginx.config_dump","title":"Full loaded config (nginx -T)","summary":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"Show what nginx loaded","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1); status=$?\nprintf '%s\\n' \"$dump\" | head -800\nexit $status\n"]}},{"id":"nginx.connections_now","title":"Active connections (stub_status)","summary":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","description":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Live conn counts","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.error_tail","title":"Tail nginx error log","summary":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","description":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/error.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Path to error log. Omit to use $NGINX_ERROR_LOG, else /var/log/nginx/error.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ERROR_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 200 error log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ERROR_LOG:-/var/log/nginx/error.log}\"\n[ -r \"$log\" ] || { echo \"error log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\"\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 4[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 5[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.master_pid","title":"nginx master PID","summary":"Read /run/nginx.pid (or the configured pid path). Read-only.","description":"Read /run/nginx.pid (or the configured pid path). Read-only.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Get the master PID","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/run/nginx.pid"]}},{"id":"nginx.quit_graceful","title":"nginx graceful quit","summary":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","description":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","kind":"exec","risk":"high","side_effects":["Workers stop accepting new connections.","In-flight requests complete; workers exit when done."],"args":[],"examples":[{"title":"Drain + exit","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","quit"]}},{"id":"nginx.reload","title":"nginx reload","summary":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","description":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","kind":"exec","risk":"high","side_effects":["Master spawns new workers.","Old workers drain in-flight requests then exit.","Listen-socket changes (new ports, removed ports) take effect."],"args":[],"examples":[{"title":"Reload config after editing","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","reload"]}},{"id":"nginx.slow_requests","title":"Slowest requests (last N lines)","summary":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","description":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N slowest to return.","validation":{"min":1,"max":200}},{"name":"column","type":"integer","required":false,"default":11,"description":"Column number containing $request_time.","validation":{"min":1,"max":50}}],"examples":[{"title":"30 slowest requests","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk -v c={{ args.column }} '{print $c, $0}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.ssl_cert_expiry","title":"TLS cert expiry for one vhost","summary":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","description":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"Server Name Indication (the vhost to probe).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Expiry for example.com vhost","args":{"sni":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","chain=$(openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" </dev/null 2>&1) || {\n  printf '%s\\n' \"$chain\" >&2\n  exit 1\n}\nprintf '%s\\n' \"$chain\" | openssl x509 -noout -dates -subject -issuer\n","emisar","{{ args.sni }}"]}},{"id":"nginx.ssl_chain_check","title":"TLS chain dump for one vhost","summary":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","description":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"SNI to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for api.example.com","args":{"sni":"api.example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.sni }}"]}},{"id":"nginx.status","title":"Nginx stub_status","summary":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","description":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL on the runner host. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Stub_status from default URL","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.stop_immediate","title":"nginx stop (immediate)","summary":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","description":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","kind":"exec","risk":"critical","side_effects":["Workers SIGTERM immediately.","In-flight requests dropped."],"args":[],"examples":[{"title":"Force-stop nginx","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","stop"]}},{"id":"nginx.test_config","title":"nginx -t","summary":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","description":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","kind":"exec","risk":"low","side_effects":["One nginx -t invocation.","Opens files referenced in the config (logs, modules).","Does NOT change runtime state."],"args":[],"examples":[{"title":"Validate nginx config","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-t"]}},{"id":"nginx.upstream_list","title":"List configured upstream blocks","summary":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","description":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"All upstreams","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | awk '/upstream /{p=1; print; next} p && /\\}/{p=0; print; next} p'\n"]}},{"id":"nginx.vhost_list","title":"List configured server_name + listen blocks","summary":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","description":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation (config validation).","Read-only."],"args":[],"examples":[{"title":"All configured vhosts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | grep -E '^\\s*(server_name|listen)\\b'\n"]}},{"id":"nginx.worker_count","title":"Live worker process count","summary":"Count the workers spawned by the master via pgrep. Read-only.","description":"Count the workers spawned by the master via pgrep. Read-only.","kind":"exec","risk":"low","side_effects":["One pgrep invocation.","Read-only."],"args":[],"examples":[{"title":"Worker count","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","MP=$(cat /run/nginx.pid 2>/dev/null); [ -n \"$MP\" ] && pgrep -c -P \"$MP\" || echo 0"]}}]},{"version":"0.2.16","content_hash":"sha256:e61b81c5b9e369db90567a8afa59f27a717a24ecc851a8d90522c08ad77dd0d7","tarball_url":"https://registry.emisar.dev/v1/packs/nginx/0.2.16/e61b81c5b9e369db90567a8afa59f27a717a24ecc851a8d90522c08ad77dd0d7/pack.tar.gz","actions":[{"id":"nginx.access_top_clients","title":"Top client IPs from access log","summary":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","description":"Tail the access log and return the top N source IPs by hit count. Assumes the default combined log format (client IP in column 1). Use to spot abusive crawlers or single-host traffic spikes that hint at a misconfigured client. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N IPs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 source IPs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $1}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.access_top_urls","title":"Top URLs from access log","summary":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","description":"Tail the access log, extract the request path, and return the top N by hit count. Assumes the default combined log format. Use to spot a noisy endpoint, a misbehaving crawler, or to size a cache. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to analyze.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}},{"name":"log_path","type":"string","required":false,"description":"Path to access log. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Top 30 URLs from last 100k lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{print $7}' | sort | uniq -c | sort -nr | head -n {{ args.limit }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.active_version","title":"Active nginx version + build","summary":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","description":"Run `nginx -V` and return the version + compile-time flags. Use to confirm which modules are compiled in (e.g. ngx_http_v2, ngx_http_realip) before recommending a config that depends on one. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"nginx -V","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-V"]}},{"id":"nginx.bytes_by_url","title":"Top URLs by total bytes sent","summary":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","description":"List top N URLs ordered by `$body_bytes_sent` summed per URL (column 10). Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N URLs.","validation":{"min":1,"max":200}}],"examples":[{"title":"Top URLs by traffic","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk '{bytes[$7]+=$10} END{for(u in bytes) printf \"%d %s\\n\", bytes[u], u}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.compiled_modules","title":"Compiled-in nginx modules","summary":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","description":"Parse `nginx -V` to list `--with-*` and `--add-module` flags. Use to confirm a needed module (http_v2, realip, brotli) is present.","kind":"exec","risk":"low","side_effects":["One nginx -V invocation.","Read-only."],"args":[],"examples":[{"title":"Module list","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nginx -V 2>&1 | tr ' ' '\\n' | grep -E '^--(with|add)'"]}},{"id":"nginx.config_dump","title":"Full loaded config (nginx -T)","summary":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump the loaded config — main + all includes — via `nginx -T`. Config text can carry secrets (authorization headers set via proxy_set_header, credentials embedded in proxy_pass URLs or map/return directives). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"Show what nginx loaded","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1); status=$?\nprintf '%s\\n' \"$dump\" | head -800\nexit $status\n"]}},{"id":"nginx.connections_now","title":"Active connections (stub_status)","summary":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","description":"Hit the stub_status endpoint to get active/reading/writing/waiting counts. Cheaper than `nginx.status` (less parsing). Requires `stub_status on;` enabled. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Live conn counts","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.error_tail","title":"Tail nginx error log","summary":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","description":"Return the last N lines from /var/log/nginx/error.log. Use to spot upstream connect failures, SSL handshake errors, or worker crashes immediately after a reload. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/error.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"How many tail lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Path to error log. Omit to use $NGINX_ERROR_LOG, else /var/log/nginx/error.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ERROR_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 200 error log lines","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ERROR_LOG:-/var/log/nginx/error.log}\"\n[ -r \"$log\" ] || { echo \"error log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\"\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 4xx status codes. Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 4[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","description":"Grep the access log for 5xx status codes (assumes combined log format). Needs the log on disk — the official container image symlinks it to stdout, where the host's log collector owns it instead. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $NGINX_ACCESS_LOG, else /var/log/nginx/access.log. Constrained to /var/log/nginx — a host whose logs live elsewhere declares that in NGINX_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/nginx/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/nginx"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E ' 5[0-9][0-9] ' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"nginx.master_pid","title":"nginx master PID","summary":"Read /run/nginx.pid (or the configured pid path). Read-only.","description":"Read /run/nginx.pid (or the configured pid path). Read-only.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"Get the master PID","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/run/nginx.pid"]}},{"id":"nginx.quit_graceful","title":"nginx graceful quit","summary":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","description":"`nginx -s quit` — workers finish in-flight requests, then exit. No new connections accepted. Use to drain before host shutdown.","kind":"exec","risk":"high","side_effects":["Workers stop accepting new connections.","In-flight requests complete; workers exit when done."],"args":[],"examples":[{"title":"Drain + exit","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","quit"]}},{"id":"nginx.reload","title":"nginx reload","summary":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","description":"Send SIGHUP to the master process. Master parses the new config, spawns new workers, gracefully drains old workers. If the new config is invalid the master logs the error and keeps the old workers — the request is non-fatal. ALWAYS run `nginx.test_config` first.","kind":"exec","risk":"high","side_effects":["Master spawns new workers.","Old workers drain in-flight requests then exit.","Listen-socket changes (new ports, removed ports) take effect."],"args":[],"examples":[{"title":"Reload config after editing","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","reload"]}},{"id":"nginx.slow_requests","title":"Slowest requests (last N lines)","summary":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","description":"List top N requests sorted by `$request_time`. Requires a log_format that includes `$request_time` as a specific column; default assumes column 11. Read-only.","kind":"exec","risk":"low","side_effects":["Reads /var/log/nginx/access.log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100000,"description":"How many tail lines to scan.","validation":{"min":1000,"max":1000000}},{"name":"limit","type":"integer","required":false,"default":30,"description":"Top-N slowest to return.","validation":{"min":1,"max":200}},{"name":"column","type":"integer","required":false,"default":11,"description":"Column number containing $request_time.","validation":{"min":1,"max":50}}],"examples":[{"title":"30 slowest requests","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","log=\"${NGINX_ACCESS_LOG:-/var/log/nginx/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ntail -n {{ args.lines }} \"$log\" | awk -v c={{ args.column }} '{print $c, $0}' | sort -rn | head -n {{ args.limit }}\n"]}},{"id":"nginx.ssl_cert_expiry","title":"TLS cert expiry for one vhost","summary":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","description":"Probe localhost:443 with SNI to read the cert expiry. Returns notBefore/notAfter and subject/issuer.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"Server Name Indication (the vhost to probe).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Expiry for example.com vhost","args":{"sni":"example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer","emisar","{{ args.sni }}"]}},{"id":"nginx.ssl_chain_check","title":"TLS chain dump for one vhost","summary":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","description":"Probe localhost:443 with SNI and dump the certificate chain. Use to confirm the intermediate cert is being served.","kind":"exec","risk":"low","side_effects":["One openssl s_client to localhost.","Read-only."],"args":[{"name":"sni","type":"string","required":true,"description":"SNI to probe.","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}},{"name":"port","type":"integer","required":false,"default":443,"description":"Port to probe.","validation":{"min":1,"max":65535}}],"examples":[{"title":"Chain for api.example.com","args":{"sni":"api.example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl s_client -connect 127.0.0.1:{{ args.port }} -servername \"$1\" -showcerts </dev/null 2>/dev/null","emisar","{{ args.sni }}"]}},{"id":"nginx.status","title":"Nginx stub_status","summary":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","description":"Fetch the nginx stub_status endpoint over loopback. Returns active connections, total requests, reading/writing/waiting counts. Requires `stub_status on;` in a location block reachable from 127.0.0.1. Loopback-only — the host is pinned to 127.0.0.1/localhost/[::1]; only the port and path vary. Read-only.","kind":"exec","risk":"low","side_effects":["One curl to the local nginx over loopback.","Read-only."],"args":[{"name":"url","type":"string","required":false,"default":"http://127.0.0.1/nginx_status","description":"stub_status URL on the runner host. Host is pinned to loopback (127.0.0.1, localhost, or [::1]); pass a non-default port/path here.","validation":{"pattern":"^https?://(127\\.0\\.0\\.1|localhost|\\[::1\\])(:[0-9]{1,5})?(/[A-Za-z0-9._~/-]{0,512})?$"}}],"examples":[{"title":"Stub_status from default URL","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-fsS","--globoff","--proto","=http,https","--max-time","5","{{ args.url }}"]}},{"id":"nginx.stop_immediate","title":"nginx stop (immediate)","summary":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","description":"`nginx -s stop` — workers stop NOW. In-flight requests are dropped mid-byte. Prefer `nginx.quit_graceful` unless the server is hung.","kind":"exec","risk":"critical","side_effects":["Workers SIGTERM immediately.","In-flight requests dropped."],"args":[],"examples":[{"title":"Force-stop nginx","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-s","stop"]}},{"id":"nginx.test_config","title":"nginx -t","summary":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","description":"Run `nginx -t`. Validates the loaded config without applying. Use before every `nginx.reload`. A failing config returns non-zero exit and the error lines go to stderr.","kind":"exec","risk":"low","side_effects":["One nginx -t invocation.","Opens files referenced in the config (logs, modules).","Does NOT change runtime state."],"args":[],"examples":[{"title":"Validate nginx config","args":{}}],"search_terms":[],"command":{"binary":"nginx","argv":["-t"]}},{"id":"nginx.upstream_list","title":"List configured upstream blocks","summary":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","description":"Grep `nginx -T` for `upstream` + `server` directives inside upstream blocks. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation.","Read-only."],"args":[],"examples":[{"title":"All upstreams","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | awk '/upstream /{p=1; print; next} p && /\\}/{p=0; print; next} p'\n"]}},{"id":"nginx.vhost_list","title":"List configured server_name + listen blocks","summary":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","description":"Grep `nginx -T` output for `server_name` and `listen` directives — a compact view of every virtual host this nginx serves. Read-only.","kind":"exec","risk":"low","side_effects":["One nginx -T invocation (config validation).","Read-only."],"args":[],"examples":[{"title":"All configured vhosts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","dump=$(nginx -T 2>&1) || { printf '%s\\n' \"$dump\" >&2; exit 1; }\nprintf '%s\\n' \"$dump\" | grep -E '^\\s*(server_name|listen)\\b'\n"]}},{"id":"nginx.worker_count","title":"Live worker process count","summary":"Count the workers spawned by the master via pgrep. Read-only.","description":"Count the workers spawned by the master via pgrep. Read-only.","kind":"exec","risk":"low","side_effects":["One pgrep invocation.","Read-only."],"args":[],"examples":[{"title":"Worker count","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","MP=$(cat /run/nginx.pid 2>/dev/null); [ -n \"$MP\" ] && pgrep -c -P \"$MP\" || echo 0"]}}]}],"retired_below":"0.2.15"},{"id":"nic","name":"NIC / ethtool diagnostics","version":"0.1.3","description":"Inspect physical network interface cards via ethtool: driver and firmware versions across every NIC (the \"what firmware is my i40e fleet running?\" check), plus per-interface link settings, hardware counters, offload features, and ring-buffer sizes. Read-only — no ethtool SET operations.","vendor":"emisar","homepage":"https://emisar.dev/packs/nic","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/nic","content_hash":"sha256:16c6174d1f6bf7d1abc5d0e5c6067dd5c2f87bcc37200341f869ab7abf63a667","tarball_url":"https://registry.emisar.dev/v1/packs/nic/0.1.3/16c6174d1f6bf7d1abc5d0e5c6067dd5c2f87bcc37200341f869ab7abf63a667/pack.tar.gz","requires":{"os":["linux"],"binaries":["ethtool"]},"detect":{"binaries":["ethtool"],"processes":[],"ports":[]},"setup":{"summary":"Reads NIC driver / firmware / link state via ethtool. No credentials needed, and nothing here changes NIC configuration — every action is a read-only ethtool GET, which runs as the unprivileged runner user (the kernel allows ethtool GETs, including statistics, without CAP_NET_ADMIN).","notes":["Read-only by construction: the pack uses only ethtool GET flags (-i, -S, -k, -g, and bare link), never the config-changing counterparts (-K, -G, -A, -C, -s). Interface arguments are validated to start with a letter, so a value can't be slipped in as an ethtool option flag.","Interface arguments are physical device names (e.g. eth0, eno1, enp24s0f0). nic.firmware scans every NIC that has a `/sys/class/net/*/device` link and skips virtual interfaces (lo, veth, bonds, bridges)."],"verify":"nic.firmware"},"actions":[{"id":"nic.driver_info","title":"ethtool -i <iface>","summary":"Show full driver info for one NIC — driver, driver version, firmware-version, expansion-ROM version, bus-info, and the supports-* capability flags.","description":"Show full driver info for one NIC — driver, driver version, firmware-version, expansion-ROM version, bus-info, and the supports-* capability flags.","kind":"exec","risk":"low","side_effects":["One ethtool -i call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Driver info for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-i","{{ args.iface }}"]}},{"id":"nic.features","title":"ethtool -k <iface>","summary":"Show offload feature state for one NIC — checksum offload, GRO/GSO/TSO, scatter-gather, RX/TX hashing, and which are fixed vs tunable. Useful when chasing throughput or checksum-related issues.","description":"Show offload feature state for one NIC — checksum offload, GRO/GSO/TSO, scatter-gather, RX/TX hashing, and which are fixed vs tunable. Useful when chasing throughput or checksum-related issues.","kind":"exec","risk":"low","side_effects":["One ethtool -k call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Offload features for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-k","{{ args.iface }}"]}},{"id":"nic.firmware","title":"NIC driver + firmware versions (all interfaces)","summary":"List driver, driver version, firmware-version, and PCI bus address for every physical NIC on the host — one line each, from `ethtool -i`. Optionally filter to a single driver (e.g. i40e). The fleet \"what firmware is each NIC running?\" check.","description":"List driver, driver version, firmware-version, and PCI bus address for every physical NIC on the host — one line each, from `ethtool -i`. Optionally filter to a single driver (e.g. i40e). The fleet \"what firmware is each NIC running?\" check.","kind":"exec","risk":"low","side_effects":["One `ethtool -i` per physical NIC.","Read-only."],"args":[{"name":"driver","type":"string","required":false,"default":"","description":"Only report NICs using this driver (e.g. i40e). Empty = all drivers.","validation":{"pattern":"^[a-zA-Z0-9._-]{0,32}$"}}],"examples":[{"title":"All NICs","args":{}},{"title":"Only i40e NICs","args":{"driver":"i40e"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","for d in /sys/class/net/*; do iface=${d##*/}; [ -e \"$d/device\" ] || continue; info=$(ethtool -i \"$iface\" 2>/dev/null) || continue; drv=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^driver: //p\"); [ -n \"$DRIVER\" ] && [ \"$drv\" != \"$DRIVER\" ] && continue; ver=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^version: //p\"); fw=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^firmware-version: //p\"); bus=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^bus-info: //p\"); printf \"%-14s driver=%-10s version=%-16s firmware=%-26s bus=%s\\n\" \"$iface\" \"$drv\" \"$ver\" \"$fw\" \"$bus\"; done"]}},{"id":"nic.link","title":"ethtool <iface>","summary":"Show link settings for one NIC — negotiated speed and duplex, autoneg, port/medium, and the link-detected flag. The \"is this NIC up and at the speed I expect?\" check.","description":"Show link settings for one NIC — negotiated speed and duplex, autoneg, port/medium, and the link-detected flag. The \"is this NIC up and at the speed I expect?\" check.","kind":"exec","risk":"low","side_effects":["One ethtool call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Link state for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["{{ args.iface }}"]}},{"id":"nic.ring","title":"ethtool -g <iface>","summary":"Show RX/TX ring-buffer sizes for one NIC — the hardware preset maximums and the current settings. Small rings under bursty load show up as rx_dropped in nic.stats.","description":"Show RX/TX ring-buffer sizes for one NIC — the hardware preset maximums and the current settings. Small rings under bursty load show up as rx_dropped in nic.stats.","kind":"exec","risk":"low","side_effects":["One ethtool -g call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Ring sizes for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-g","{{ args.iface }}"]}},{"id":"nic.stats","title":"ethtool -S <iface>","summary":"Show hardware + driver counters for one NIC — per-queue and total rx/tx packets, bytes, errors, drops, and discards. The place to look for packet loss that ip/ifconfig counters don't break out.","description":"Show hardware + driver counters for one NIC — per-queue and total rx/tx packets, bytes, errors, drops, and discards. The place to look for packet loss that ip/ifconfig counters don't break out.","kind":"exec","risk":"low","side_effects":["One ethtool -S call.","Read-only (a GET; the kernel allows it without CAP_NET_ADMIN)."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Counters for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-S","{{ args.iface }}"]}}],"previous_versions":[{"version":"0.1.1","content_hash":"sha256:fe4e1d8a7e8633d57d95197103c8260d7b1273106595bae24c70efcacf65956d","tarball_url":"https://registry.emisar.dev/v1/packs/nic/0.1.1/fe4e1d8a7e8633d57d95197103c8260d7b1273106595bae24c70efcacf65956d/pack.tar.gz","actions":[{"id":"nic.driver_info","title":"ethtool -i <iface>","summary":"Show full driver info for one NIC — driver, driver version, firmware-version, expansion-ROM version, bus-info, and the supports-* capability flags.","description":"Show full driver info for one NIC — driver, driver version, firmware-version, expansion-ROM version, bus-info, and the supports-* capability flags.","kind":"exec","risk":"low","side_effects":["One ethtool -i call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Driver info for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-i","{{ args.iface }}"]}},{"id":"nic.features","title":"ethtool -k <iface>","summary":"Show offload feature state for one NIC — checksum offload, GRO/GSO/TSO, scatter-gather, RX/TX hashing, and which are fixed vs tunable. Useful when chasing throughput or checksum-related issues.","description":"Show offload feature state for one NIC — checksum offload, GRO/GSO/TSO, scatter-gather, RX/TX hashing, and which are fixed vs tunable. Useful when chasing throughput or checksum-related issues.","kind":"exec","risk":"low","side_effects":["One ethtool -k call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Offload features for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-k","{{ args.iface }}"]}},{"id":"nic.firmware","title":"NIC driver + firmware versions (all interfaces)","summary":"List driver, driver version, firmware-version, and PCI bus address for every physical NIC on the host — one line each, from `ethtool -i`. Optionally filter to a single driver (e.g. i40e). The fleet \"what firmware is each NIC running?\" check.","description":"List driver, driver version, firmware-version, and PCI bus address for every physical NIC on the host — one line each, from `ethtool -i`. Optionally filter to a single driver (e.g. i40e). The fleet \"what firmware is each NIC running?\" check.","kind":"exec","risk":"low","side_effects":["One `ethtool -i` per physical NIC.","Read-only."],"args":[{"name":"driver","type":"string","required":false,"default":"","description":"Only report NICs using this driver (e.g. i40e). Empty = all drivers.","validation":{"pattern":"^[a-zA-Z0-9._-]{0,32}$"}}],"examples":[{"title":"All NICs","args":{}},{"title":"Only i40e NICs","args":{"driver":"i40e"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","for d in /sys/class/net/*; do iface=${d##*/}; [ -e \"$d/device\" ] || continue; info=$(ethtool -i \"$iface\" 2>/dev/null) || continue; drv=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^driver: //p\"); [ -n \"$DRIVER\" ] && [ \"$drv\" != \"$DRIVER\" ] && continue; ver=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^version: //p\"); fw=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^firmware-version: //p\"); bus=$(printf \"%s\\n\" \"$info\" | sed -n \"s/^bus-info: //p\"); printf \"%-14s driver=%-10s version=%-16s firmware=%-26s bus=%s\\n\" \"$iface\" \"$drv\" \"$ver\" \"$fw\" \"$bus\"; done"]}},{"id":"nic.link","title":"ethtool <iface>","summary":"Show link settings for one NIC — negotiated speed and duplex, autoneg, port/medium, and the link-detected flag. The \"is this NIC up and at the speed I expect?\" check.","description":"Show link settings for one NIC — negotiated speed and duplex, autoneg, port/medium, and the link-detected flag. The \"is this NIC up and at the speed I expect?\" check.","kind":"exec","risk":"low","side_effects":["One ethtool call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Link state for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["{{ args.iface }}"]}},{"id":"nic.ring","title":"ethtool -g <iface>","summary":"Show RX/TX ring-buffer sizes for one NIC — the hardware preset maximums and the current settings. Small rings under bursty load show up as rx_dropped in nic.stats.","description":"Show RX/TX ring-buffer sizes for one NIC — the hardware preset maximums and the current settings. Small rings under bursty load show up as rx_dropped in nic.stats.","kind":"exec","risk":"low","side_effects":["One ethtool -g call.","Read-only."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Ring sizes for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-g","{{ args.iface }}"]}},{"id":"nic.stats","title":"ethtool -S <iface>","summary":"Show hardware + driver counters for one NIC — per-queue and total rx/tx packets, bytes, errors, drops, and discards. The place to look for packet loss that ip/ifconfig counters don't break out.","description":"Show hardware + driver counters for one NIC — per-queue and total rx/tx packets, bytes, errors, drops, and discards. The place to look for packet loss that ip/ifconfig counters don't break out.","kind":"exec","risk":"low","side_effects":["One ethtool -S call.","Read-only (a GET; the kernel allows it without CAP_NET_ADMIN)."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (e.g. eth0, eno1, enp24s0f0).","validation":{"pattern":"^[a-zA-Z][a-zA-Z0-9._-]{0,14}$"}}],"examples":[{"title":"Counters for eth0","args":{"iface":"eth0"}}],"search_terms":[],"command":{"binary":"ethtool","argv":["-S","{{ args.iface }}"]}}]}]},{"id":"nodejs-pm2","name":"Node.js / PM2 operations","version":"0.1.14","description":"PM2 process inventory + logs + per-app introspection, plus narrow mutators (restart, reload, stop, scale). Requires the runner to be the same uid as the PM2 daemon (or set PM2_HOME).","vendor":"emisar","homepage":"https://emisar.dev/packs/nodejs-pm2","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/nodejs-pm2","content_hash":"sha256:d81f2a2033ff6984981888cc9cdfe62cd6298ae6e991f81bdda3bdf921a50e8f","tarball_url":"https://registry.emisar.dev/v1/packs/nodejs-pm2/0.1.14/d81f2a2033ff6984981888cc9cdfe62cd6298ae6e991f81bdda3bdf921a50e8f/pack.tar.gz","requires":{"os":["linux"],"binaries":["pm2","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the local pm2 CLI on the runner host — no credentials needed.","notes":["pm2 talks to a per-user daemon, so the runner must run as the same user that owns the target pm2 processes; running as a different uid (or root) sees a different, usually empty, process list.","If the apps run under a daemon at a non-default location, set PM2_HOME to that directory (and add it to the runner's `inherit_env`)."],"verify":"pm2.list"},"actions":[{"id":"pm2.describe","title":"pm2 describe <name>","summary":"Show config + runtime details for one process (status, restarts, uptime, script path, resources). Read-only. Per-process environment is projected out — use `pm2.env` for one process's effective env.","description":"Show config + runtime details for one process (status, restarts, uptime, script path, resources). Read-only. Per-process environment is projected out — use `pm2.env` for one process's effective env.","kind":"exec","risk":"low","side_effects":["One PM2 IPC call.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Describe one","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","procs=$(pm2 jlist) || exit 1; printf '%s' \"$procs\" | jq --arg n \"${1}\" 'map(select(.name == $n or (.pm_id|tostring) == $n)) | map({name, pm_id, pid, monit, namespace: .pm2_env.namespace, status: .pm2_env.status, uptime: .pm2_env.pm_uptime, restarts: .pm2_env.restart_time, unstable_restarts: .pm2_env.unstable_restarts, mode: .pm2_env.exec_mode, instances: .pm2_env.instances, script: .pm2_env.pm_exec_path, cwd: .pm2_env.pm_cwd, interpreter: .pm2_env.exec_interpreter, node_args: .pm2_env.node_args, created_at: .pm2_env.created_at, version: .pm2_env.version, autorestart: .pm2_env.autorestart, max_memory_restart: .pm2_env.max_memory_restart})'","emisar","{{ args.name }}"]}},{"id":"pm2.dump","title":"pm2 dump","summary":"Persist the current process list so PM2 resurrects it on boot.","description":"Persist the current process list so PM2 resurrects it on boot.","kind":"exec","risk":"medium","side_effects":["Writes ~/.pm2/dump.pm2.","Future PM2 resurrects will use this snapshot."],"args":[],"examples":[{"title":"Save startup list","args":{}}],"search_terms":[],"command":{"binary":"pm2","argv":["dump"]}},{"id":"pm2.env","title":"pm2 env <id>","summary":"Show effective environment for one process (post-merge of system + app env).","description":"Show effective environment for one process (post-merge of system + app env).","kind":"exec","risk":"high","side_effects":["One PM2 IPC call.","Read-only, but it prints the process's whole environment.","The app operator names those variables, so no rule set can enumerate the secret-bearing ones; redaction here is a best-effort backstop."],"args":[{"name":"id","type":"integer","required":true,"description":"PM2 process id.","validation":{"min":0,"max":1000}}],"examples":[{"title":"Env for id 0","args":{"id":0}}],"search_terms":[],"command":{"binary":"pm2","argv":["env","{{ args.id }}"]}},{"id":"pm2.error_logs","title":"pm2 logs <name> --err --lines N --nostream","summary":"Tail the last N stderr-only lines for one process.","description":"Tail the last N stderr-only lines for one process.","kind":"exec","risk":"medium","side_effects":["Reads PM2 log files.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines to tail.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Stderr only","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["logs","{{ args.name }}","--err","--lines","{{ args.lines }}","--nostream"]}},{"id":"pm2.flush_logs","title":"pm2 flush <name>","summary":"Empty PM2 log files for one process. Existing log content is lost.","description":"Empty PM2 log files for one process. Existing log content is lost.","kind":"exec","risk":"medium","side_effects":["Truncates the stdout + stderr log files for the named process.","Log file inodes are reused; tailers may need to re-open."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Empty logs","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["flush","{{ args.name }}"]}},{"id":"pm2.jlist","title":"pm2 jlist","summary":"List PM2 processes as JSON with status, uptime, restarts, mode, and CPU/mem. Read-only. Per-process environment is projected out — use `pm2.env` for one process's effective env.","description":"List PM2 processes as JSON with status, uptime, restarts, mode, and CPU/mem. Read-only. Per-process environment is projected out — use `pm2.env` for one process's effective env.","kind":"exec","risk":"low","side_effects":["One PM2 IPC call.","Read-only."],"args":[],"examples":[{"title":"JSON process list","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","procs=$(pm2 jlist) || exit 1; printf '%s' \"$procs\" | jq 'map({name, pm_id, pid, monit, status: .pm2_env.status, uptime: .pm2_env.pm_uptime, restarts: .pm2_env.restart_time, mode: .pm2_env.exec_mode})'"]}},{"id":"pm2.list","title":"pm2 list","summary":"List all processes managed by PM2 with status, uptime, restarts, CPU/mem.","description":"List all processes managed by PM2 with status, uptime, restarts, CPU/mem.","kind":"exec","risk":"low","side_effects":["One PM2 IPC call.","Read-only."],"args":[],"examples":[{"title":"All PM2 processes","args":{}}],"search_terms":[],"command":{"binary":"pm2","argv":["list"]}},{"id":"pm2.logs","title":"pm2 logs <name> --lines N --nostream","summary":"Tail the last N stdout+stderr lines for one process.","description":"Tail the last N stdout+stderr lines for one process.","kind":"exec","risk":"medium","side_effects":["Reads PM2 log files.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines to tail.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 200 lines","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["logs","{{ args.name }}","--lines","{{ args.lines }}","--nostream"]}},{"id":"pm2.monit_snapshot","title":"pm2 monit snapshot (CPU + memory)","summary":"Show one-shot CPU + memory snapshot for every process as JSON. Read-only. Per-process environment is projected out — use `pm2.env` for one process's effective env.","description":"Show one-shot CPU + memory snapshot for every process as JSON. Read-only. Per-process environment is projected out — use `pm2.env` for one process's effective env.","kind":"exec","risk":"low","side_effects":["One PM2 IPC call.","Read-only."],"args":[],"examples":[{"title":"Monit snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","procs=$(pm2 jlist) || exit 1; printf '%s' \"$procs\" | jq 'map({name, pm_id, pid, monit, status: .pm2_env.status, uptime: .pm2_env.pm_uptime, restarts: .pm2_env.restart_time})'"]}},{"id":"pm2.node_version","title":"node --version","summary":"Show Node.js runtime version (system default).","description":"Show Node.js runtime version (system default).","kind":"exec","risk":"low","side_effects":["Forks node.","Read-only."],"args":[],"examples":[{"title":"Node version","args":{}}],"search_terms":[],"command":{"binary":"node","argv":["--version"]}},{"id":"pm2.pm2_version","title":"pm2 -v","summary":"Show PM2 daemon version.","description":"Show PM2 daemon version.","kind":"exec","risk":"low","side_effects":["One PM2 IPC call.","Read-only."],"args":[],"examples":[{"title":"PM2 version","args":{}}],"search_terms":[],"command":{"binary":"pm2","argv":["-v"]}},{"id":"pm2.reload","title":"pm2 reload <name>","summary":"Zero-downtime reload — only safe for cluster-mode apps. For fork-mode, behaves like restart.","description":"Zero-downtime reload — only safe for cluster-mode apps. For fork-mode, behaves like restart.","kind":"exec","risk":"high","side_effects":["Cluster mode: rolling worker swap, no dropped requests.","Fork mode: equivalent to restart — drops in-flight requests."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Reload one","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["reload","{{ args.name }}"]}},{"id":"pm2.restart","title":"pm2 restart <name>","summary":"Hard-restart one process (kill + spawn). Drops in-flight requests.","description":"Hard-restart one process (kill + spawn). Drops in-flight requests.","kind":"exec","risk":"high","side_effects":["Process is killed and respawned.","Open sockets close; in-flight requests drop."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart one","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["restart","{{ args.name }}"]}},{"id":"pm2.scale","title":"pm2 scale <name> <N>","summary":"Set the number of cluster-mode workers for one app. No-op for fork mode.","description":"Set the number of cluster-mode workers for one app. No-op for fork mode.","kind":"exec","risk":"high","side_effects":["PM2 adds or removes worker processes.","Scale-down causes graceful worker shutdown."],"args":[{"name":"name","type":"string","required":true,"description":"Process name (cluster-mode).","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"instances","type":"integer","required":true,"description":"Target worker count.","validation":{"min":1,"max":128}}],"examples":[{"title":"Scale to 4 workers","args":{"instances":4,"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["scale","{{ args.name }}","{{ args.instances }}"]}},{"id":"pm2.stop","title":"pm2 stop <name>","summary":"Stop one process (PM2 won't auto-restart until you `start`/`restart`).","description":"Stop one process (PM2 won't auto-restart until you `start`/`restart`).","kind":"exec","risk":"high","side_effects":["Process is stopped.","PM2 marks it `stopped`; it will not auto-respawn."],"args":[{"name":"name","type":"string","required":true,"description":"Process name or id.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Stop one","args":{"name":"api"}}],"search_terms":[],"command":{"binary":"pm2","argv":["stop","{{ args.name }}"]}}],"retired_below":"0.1.13"},{"id":"nomad","name":"HashiCorp Nomad","version":"0.4.3","description":"Deep Nomad operations — full job lifecycle (inspect, history, scale horizontally + vertically, dispatch, revert, promote, stop + start again, batched whole-job restart, forced re-evaluation), meta-filtered discovery (list jobs with their meta stanza, or every allocation of e.g. managed_by=terraform jobs, filtered server-side), per-task CPU/memory resource read + set, allocation introspection + health checks + filesystem ls/stat (metadata only, never file contents) + fixed in-container Redis probes (ping/info via alloc exec, no freeform command) + restart + signal + stop, bounded job health snapshots, job-spec-declared actions (run a command the job author defined), native service discovery (no Consul) — every namespace-bound action takes an optional namespace, and high-use reads also take an optional region — node fleet management (drain, eligibility, purge), node pools, evaluation + deployment status and control (pause, resume, fail/abort a rollout), operator raft + autopilot, CSI volumes + plugin health, host volumes, variable metadata (never values), ACL policies + tokens, namespaces + quotas. Authenticates via NOMAD_ADDR + NOMAD_TOKEN (and the standard TLS env) on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/nomad","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/nomad","content_hash":"sha256:1ee566b5e8a02a1fb6ccd5ebc3abeafe4c4c33d0289a9f6694b58f1b07dee4e1","tarball_url":"https://registry.emisar.dev/v1/packs/nomad/0.4.3/1ee566b5e8a02a1fb6ccd5ebc3abeafe4c4c33d0289a9f6694b58f1b07dee4e1/pack.tar.gz","requires":{"os":["linux"],"binaries":["nomad","jq","timeout"]},"detect":{"binaries":[],"processes":["nomad"],"ports":[4646]},"setup":{"summary":"Every action goes through the nomad CLI (the API reads via `nomad operator api`), so the server address, ACL token, and TLS material are read uniformly from the standard NOMAD_* env on the runner host.","env":[{"name":"NOMAD_ADDR","description":"Server HTTP address, including scheme.","default":"http://127.0.0.1:4646","example":"http://nomad.internal:4646"},{"name":"NOMAD_TOKEN","description":"ACL token. Required when ACLs are enabled; its policy gates which actions succeed."},{"name":"NOMAD_CACERT","description":"Path to a CA certificate for verifying an https:// server signed by a private CA. Must be readable by the runner user."},{"name":"NOMAD_CLIENT_CERT","description":"Path to a client certificate for mTLS-enabled servers (pair with `NOMAD_CLIENT_KEY`)."},{"name":"NOMAD_CLIENT_KEY","description":"Path to the client certificate's private key for mTLS-enabled servers."}],"notes":["Any NOMAD_* env you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth/TLS).","With ACLs enabled the token needs the matching capabilities — submit-job for the job mutators, alloc-exec for job_action_run, node:write for drain/eligibility/purge, and operator:write for the raft remove-peer action.","API aggregation and projection actions use jq on the runner host; it is a declared pack requirement.","The API-read actions use `nomad operator api` (Nomad CLI 1.4+). Newer verbs degrade with a plain CLI error on older clusters: node pools need Nomad 1.6+, job-declared actions 1.7+, job_start 1.9+."],"verify":"nomad.agent_info"},"actions":[{"id":"nomad.acl_policies","title":"nomad acl policy list","summary":"List all ACL policy names.","description":"List all ACL policy names.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","policy","list"]}},{"id":"nomad.acl_token_self","title":"nomad acl token self","summary":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","description":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only; the Secret ID field printed by the CLI is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","token","self"]}},{"id":"nomad.agent_force_leave","title":"nomad server force-leave <node>","summary":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","description":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","kind":"exec","risk":"high","side_effects":["The named server is marked left in serf.","Raft membership unaffected — use operator raft remove-peer for that."],"args":[{"name":"node_name","type":"string","required":true,"description":"Server node name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Force one server out","args":{"node_name":"nomad-server-3"}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","force-leave","{{ args.node_name }}"]}},{"id":"nomad.agent_info","title":"nomad agent-info","summary":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","description":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent info","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["agent-info"]}},{"id":"nomad.agent_members","title":"nomad server members","summary":"List the Serf gossip pool members.","description":"List the Serf gossip pool members.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","members","-detailed"]}},{"id":"nomad.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config (member name, region, datacenter, tags).","description":"Show this agent's effective config (member name, region, datacenter, tags).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Self config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/self"]}},{"id":"nomad.alloc_checks","title":"nomad alloc checks <id>","summary":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Health checks for one alloc","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_info","title":"Show Redis INFO inside an allocation (nomad alloc exec redis-cli info)","summary":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum.","description":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.info when you can reach it directly. The command is fixed except the enum section — no freeform command, shell, host, port, or password is accepted, so it reads the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance. risk:medium, not low: `nomad alloc exec` runs inside the running container and INFO exposes memory/stats/ replication topology, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/ raw-driver tasks).","kind":"script","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli info <section>` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"section","type":"string","required":false,"default":"default","description":"INFO section (bounded enum).","validation":{"enum":["default","all","server","clients","memory","persistence","stats","replication","cpu","commandstats","latencystats","cluster","keyspace","errorstats"]}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Default INFO of Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}},{"title":"Replication topology","args":{"alloc_id":"abc12345","section":"replication","task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_ping","title":"Ping Redis inside an allocation (nomad alloc exec redis-cli ping)","summary":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG.","description":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.ping when you can reach it directly. The command is fixed — no freeform command, shell, host, port, or password is accepted, so it connects to the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance (itself a signal). risk:medium, not low: `nomad alloc exec` runs inside the running container and can expose internal state, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/raw-driver tasks).","kind":"script","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli ping` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Ping Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_fs_ls","title":"List a directory in an allocation (nomad fs/ls API)","summary":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime.","description":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime. This is the \"what files did my task write to local/ or alloc/logs\" read for debugging, with no local CLI session. It calls Nomad's fs/ls API endpoint, which returns directory metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path defaults to the alloc root (/), is relative to it (Nomad contains it to the alloc dir), and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only (directory metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":false,"default":"/","description":"Directory to list, relative to the alloc root (e.g. local, alloc/logs, secrets). Defaults to the alloc root \"/\". No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"List the alloc root","args":{"alloc_id":"abc12345"}},{"title":"List the task's local/ directory","args":{"alloc_id":"abc12345","path":"local"}}],"search_terms":[]},{"id":"nomad.alloc_fs_stat","title":"Stat a path in an allocation (nomad fs/stat API)","summary":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type.","description":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type. This is the \"does this file exist / how big is it / when was it written\" read. It calls Nomad's fs/stat API endpoint, which returns metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path is relative to the alloc root (Nomad contains it to the alloc dir) and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only (file metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"Path to stat, relative to the alloc root (e.g. local/app.log, secrets/.env). No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stat a task's log file","args":{"alloc_id":"abc12345","path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_fs_tail","title":"Tail a file inside an allocation (nomad alloc fs -tail)","summary":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say.","description":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say. Unlike nomad.alloc_logs, which returns a task's stdout or stderr stream, this reads a FILE the task wrote. It is medium rather than low because a rendered template can hold whatever the job author put in it, so the content is not knowable from the action alone. Two bounds keep that honest — path rejects the secrets/ tree outright, and lines is capped — but neither can vouch for a file this action has never seen; treat the tier as the promise and the redaction as a backstop. Requires a Nomad token with read-fs on the namespace.","kind":"script","risk":"medium","side_effects":["One API call through the Nomad CLI.","Read-only; nothing in the allocation is modified.","Returns file CONTENT, unlike alloc_fs_ls and alloc_fs_stat which return metadata only. A file a job author rendered may contain anything they put in it.","The packaged script refuses the secrets/ tree before calling nomad, so Nomad's own rendered-credential mount cannot be read through this action."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"File to tail, relative to the alloc root (e.g. local/config.json, alloc/logs/app.stdout.0). The secrets/ tree is rejected — that is where Nomad mounts rendered credentials. No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*$","max_length":256}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many trailing lines to return.","validation":{"min":1,"max":500}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}}],"examples":[{"title":"Tail a rendered config file","args":{"alloc_id":"abc12345","path":"local/config.json"}},{"title":"Last 20 lines of a task's log file","args":{"alloc_id":"abc12345","lines":20,"path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_list_by_meta","title":"List allocations by job meta (GET /v1/allocations?filter=Job.Meta[…])","summary":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","description":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all allocations).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All allocations (compact)","args":{}},{"title":"Allocations of terraform-managed jobs","args":{"meta_key":"managed_by","meta_value":"terraform"}}],"search_terms":[]},{"id":"nomad.alloc_logs","title":"Tail a task's application logs — stdout (nomad alloc logs)","summary":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout.","description":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout. This is the read for \"show me the app logs\" or \"tail the service output\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs_stderr for the stderr stream (errors, stack traces, panics).","kind":"script","risk":"medium","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stdout lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stdout lines while chasing a restart","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_logs_stderr","title":"Tail a task's application logs — stderr (nomad alloc logs -stderr)","summary":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output).","description":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output). This is the read for \"show me the error logs\" or \"why did it crash\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs for the stdout stream.","kind":"script","risk":"medium","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stderr lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stderr lines after a crash","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_restart","title":"nomad alloc restart <id> [task]","summary":"Restart one task (or all tasks if not specified) in one allocation.","description":"Restart one task (or all tasks if not specified) in one allocation.","kind":"exec","risk":"high","side_effects":["Task(s) receive SIGTERM then SIGKILL after kill_timeout.","In-flight requests drop unless shutdown_delay is set."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all tasks).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Restart one task","args":{"alloc_id":"abc12345","task":"web"}}],"search_terms":["restart pod","bounce task"],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; task=$2; alloc=$3; set -- alloc restart; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; [ -z \"$task\" ] || set -- \"$@\" -task \"$task\"; exec nomad \"$@\" \"$alloc\"","emisar","{{ args.namespace }}","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_signal","title":"nomad alloc signal -s <signal> <id> [task]","summary":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","description":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","kind":"exec","risk":"high","side_effects":["Targeted task(s) receive the signal.","Effect depends on the application's signal handling."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"signal","type":"string","required":true,"description":"Signal name (HUP, USR1, USR2, etc).","validation":{"enum":["HUP","USR1","USR2","INT","TERM","QUIT"]}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"SIGHUP to reload","args":{"alloc_id":"abc12345","signal":"HUP","task":"web"}}],"search_terms":["send sighup","reload config"],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; task=$2; alloc=$3; set -- alloc signal -s {{ args.signal }}; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; [ -z \"$task\" ] || set -- \"$@\" -task \"$task\"; exec nomad \"$@\" \"$alloc\"","emisar","{{ args.namespace }}","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_stats","title":"GET /v1/client/allocation/<id>/stats","summary":"Show CPU + memory + network stats for one allocation.","description":"Show CPU + memory + network stats for one allocation.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stats","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_status","title":"nomad alloc status <id>","summary":"Show one allocation's full state — task states, restarts, last events.","description":"Show one allocation's full state — task states, restarts, last events.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One alloc","args":{"alloc_id":"abc12345"}},{"title":"One alloc in the \"prod\" namespace","args":{"alloc_id":"abc12345","namespace":"prod"}}],"search_terms":["crash loop","tasks flapping","oom killed","restart loop"]},{"id":"nomad.alloc_stop","title":"nomad alloc stop <id>","summary":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","description":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","kind":"script","risk":"high","side_effects":["Allocation is stopped + replaced.","Brief unavailability for the running container."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force-reschedule","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.csi_volume_list","title":"nomad volume status","summary":"List all registered CSI volumes with claim count + state.","description":"List all registered CSI volumes with claim count + state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"CSI volumes","args":{}},{"title":"CSI volumes in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.csi_volume_status","title":"nomad volume status <id>","summary":"Show one CSI volume's full state — claims, allocations using it, plugin status.","description":"Show one CSI volume's full state — claims, allocations using it, plugin status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"volume_id","type":"string","required":true,"description":"Volume ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"One volume","args":{"volume_id":"data-volume-1"}},{"title":"One volume in the \"prod\" namespace","args":{"namespace":"prod","volume_id":"data-volume-1"}}],"search_terms":[]},{"id":"nomad.deployment_fail","title":"nomad deployment fail <id>","summary":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","description":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","kind":"script","risk":"high","side_effects":["The rollout stops; no further canaries or placements from this deployment.","With auto_revert, the job rolls back to its last stable version."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Abort a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":["abort rollout","cancel deployment"]},{"id":"nomad.deployment_list","title":"nomad deployment list","summary":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","description":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All deployments","args":{}},{"title":"Deployments in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":["deploy stuck","rollout stalled"]},{"id":"nomad.deployment_pause","title":"nomad deployment pause <id>","summary":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","description":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","kind":"script","risk":"medium","side_effects":["No further placements from this deployment until resumed."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Pause a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.deployment_resume","title":"nomad deployment resume <id>","summary":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","description":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","kind":"script","risk":"medium","side_effects":["The rollout continues; new allocations are placed per the update stanza."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Resume a paused rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.deployment_status","title":"nomad deployment status <id>","summary":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","description":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Deployment status","args":{"deployment_id":"abc12345"}}],"search_terms":["deploy stuck","rollout stalled","deploy failing"]},{"id":"nomad.eval_list","title":"nomad eval list","summary":"List all recent evaluations across the cluster.","description":"List all recent evaluations across the cluster.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Recent evals","args":{}},{"title":"Recent evals in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.eval_status","title":"nomad eval status <id>","summary":"Show one evaluation's status — placement failures, queued allocations, blocked count.","description":"Show one evaluation's status — placement failures, queued allocations, blocked count.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"eval_id","type":"string","required":true,"description":"Evaluation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Eval status","args":{"eval_id":"abc12345"}}],"search_terms":["stuck pending","not scheduling"]},{"id":"nomad.event_snapshot","title":"Snapshot recent Nomad events (bounded /v1/event/stream)","summary":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session.","description":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session. Nomad has no \"last N events\" query: /v1/event/stream is a forward feed whose only history is the broker's replay buffer (~100 events). This reads it from index=1 (replays the buffer, then live events) for `seconds` seconds, capped at 256 KiB, then returns — so it never hangs. Optionally filter to one `topic` or one `namespace`. Output is NDJSON: one {Index, Events:[...]} batch per line. Requires a token that can read the event stream.","kind":"script","risk":"low","side_effects":["Opens the Nomad event stream for a bounded time window.","Read-only."],"args":[{"name":"seconds","type":"integer","required":false,"default":5,"description":"How long to read the stream — the snapshot window, in seconds.","validation":{"min":1,"max":15}},{"name":"topic","type":"string","required":false,"default":"","description":"Filter to one event topic (empty = all topics). One of Job, Allocation, Evaluation, Deployment, Node, Service, or an ACL topic.","validation":{"pattern":"^(Job|Allocation|Evaluation|Deployment|Node|Service|ACLToken|ACLPolicy|ACLRole|ACLAuthMethod|ACLBindingRule|NodePool)?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Filter to one namespace (empty = the runner's ambient/default).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_-]{0,127})?$"}}],"examples":[{"title":"Recent events across all topics (5s window)","args":{}},{"title":"Recent allocation events only","args":{"topic":"Allocation"}},{"title":"Recent events in one namespace, 10s window","args":{"namespace":"production","seconds":10}}],"search_terms":[]},{"id":"nomad.host_volume_list","title":"Host volumes from /v1/nodes","summary":"List host-volume declarations across all client nodes.","description":"List host-volume declarations across all client nodes.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host volumes","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/nodes"]}},{"id":"nomad.job_action_run","title":"nomad action -job <job> -group <group> -task <task> <name>","summary":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+).","description":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+). Nomad job authors declare named commands in the task's `action` blocks; this executes ONE of them by name — whatever command the job spec declares, with the task's own environment and filesystem. The pack fixes nothing about the command itself, so treat this as remote execution bounded by the job author, not by this pack. List a job's declared actions via nomad.job_inspect (TaskGroups[].Tasks[].Actions). Requires a token with alloc-exec.","kind":"script","risk":"high","side_effects":["The job-defined command runs inside the task's container/environment.","Effect depends entirely on what the job author declared."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"action_name","type":"string","required":true,"description":"The action name declared in the job spec's `action` block.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Run a job-declared action","args":{"action_name":"reload-config","group":"web","job":"api","task":"app"}}],"search_terms":[]},{"id":"nomad.job_allocations","title":"nomad job allocs <id>","summary":"List all allocations for one job.","description":"List all allocations for one job.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Allocations","args":{"job":"api"}},{"title":"Allocations in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_deployments","title":"nomad job deployments <id>","summary":"List deployment history for one job (rolling updates, canary, blue-green).","description":"List deployment history for one job (rolling updates, canary, blue-green).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Deployments","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_dispatch","title":"nomad job dispatch <id>","summary":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","description":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","kind":"exec","risk":"high","side_effects":["A new dispatched job instance is created and scheduled.","Counts toward job history."],"args":[{"name":"job","type":"string","required":true,"description":"Parameterized job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"meta_kv","type":"string","required":false,"default":"","description":"Optional meta as 'k=v,k2=v2' (no spaces around =).","validation":{"pattern":"^([a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256}(,[a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256})*)?$","max_length":1024}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Dispatch with meta","args":{"job":"batch-processor","meta_kv":"input=/tmp/data,priority=high"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; meta=$2; job=$3; set -- job dispatch; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; if [ -n \"$meta\" ]; then oldifs=$IFS; IFS=,; for kv in $meta; do set -- \"$@\" -meta \"$kv\"; done; IFS=$oldifs; fi; exec nomad \"$@\" \"$job\"","emisar","{{ args.namespace }}","{{ args.meta_kv }}","{{ args.job }}"]}},{"id":"nomad.job_eval","title":"nomad job eval <id>","summary":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","description":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","kind":"exec","risk":"medium","side_effects":["A new evaluation is created; the scheduler may place or reschedule allocations."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"force_reschedule","type":"string","required":false,"default":"false","description":"true also reschedules failed allocations that are past their reschedule limit.","validation":{"enum":["false","true"]}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Re-evaluate a job","args":{"job":"api"}},{"title":"Force failed allocs to reschedule","args":{"force_reschedule":"true","job":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; job=$2; force=$3; set -- job eval -detach; [ \"$force\" = true ] && set -- \"$@\" -force-reschedule; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; exec nomad \"$@\" -- \"$job\"","emisar","{{ args.namespace }}","{{ args.job }}","{{ args.force_reschedule }}"]}},{"id":"nomad.job_evaluations","title":"nomad job eval <id> (force re-evaluation)","summary":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","description":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","kind":"script","risk":"medium","side_effects":["Creates a new evaluation for the job.","The scheduler reconciles the job; allocations may be moved or restarted."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force a re-evaluation","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_health_snapshot","title":"Nomad job health snapshot","summary":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","description":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","kind":"script","risk":"low","side_effects":["Four fixed read-only Nomad API calls plus one checks read per returned allocation.","Allocation and event counts are bounded by validated arguments.","Read-only - never changes a job, deployment, allocation, or check."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty keeps the runner's ambient namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty keeps the runner's ambient region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}},{"name":"allocation_limit","type":"integer","required":false,"default":10,"description":"Maximum recent allocations and associated check reads.","validation":{"min":1,"max":25}},{"name":"events_per_task","type":"integer","required":false,"default":5,"description":"Maximum recent restart and failed events retained per task.","validation":{"min":1,"max":20}}],"examples":[{"title":"Recent health for an API job","args":{"job":"api"}},{"title":"Smaller production snapshot","args":{"allocation_limit":5,"events_per_task":3,"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_history","title":"nomad job history <id>","summary":"List all versions of one job with submitter + timestamp.","description":"List all versions of one job with submitter + timestamp.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"History","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_inspect","title":"nomad job inspect <id>","summary":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"script","risk":"high","side_effects":["One API call.","Read-only, but exposes the job's env/template blocks (may include secrets)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Inspect job","args":{"job":"api"}},{"title":"Inspect a job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["jobspec","job definition"]},{"id":"nomad.job_list_by_meta","title":"List jobs with meta (GET /v1/jobs?meta=true [&filter])","summary":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","description":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all jobs).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All jobs with their meta","args":{}},{"title":"Jobs managed by Terraform","args":{"meta_key":"managed_by","meta_value":"terraform"}},{"title":"One application's jobs across all namespaces","args":{"meta_key":"application","meta_value":"blitz-website","namespace":"*"}}],"search_terms":[]},{"id":"nomad.job_periodic_force","title":"nomad job periodic force <id>","summary":"Force-run one periodic job NOW, ignoring schedule.","description":"Force-run one periodic job NOW, ignoring schedule.","kind":"script","risk":"medium","side_effects":["A new periodic child job is created and dispatched.","Counts toward normal job history."],"args":[{"name":"job","type":"string","required":true,"description":"Periodic job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force-run","args":{"job":"nightly-backup"}}],"search_terms":["run cron now","trigger scheduled job"]},{"id":"nomad.job_promote","title":"nomad job promote <id>","summary":"Promote a canary deployment — replaces the rest of the allocations with the new version.","description":"Promote a canary deployment — replaces the rest of the allocations with the new version.","kind":"script","risk":"high","side_effects":["Old allocations are gradually replaced per the update stanza.","In-flight requests on replaced allocs may drop (subject to shutdown_delay)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID with an in-progress canary.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Promote canary","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_resources","title":"nomad job inspect <id> (resource summary)","summary":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","description":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","kind":"script","risk":"low","side_effects":["One read-only API call (job inspect).","Read-only — never writes or mutates job state."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Show current resources per group/task","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_restart","title":"nomad job restart <id>","summary":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","description":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","kind":"script","risk":"high","side_effects":["Every targeted task is stopped and started again, batch by batch.","In-flight requests on restarting allocs may drop (subject to shutdown_delay).","mode=migrate reschedules allocations, possibly onto different nodes."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"batch_size","type":"string","required":false,"default":"1","description":"Allocations per batch — a count (\"2\") or a percentage of running allocs (\"25%\").","validation":{"pattern":"^[1-9][0-9]{0,3}%?$"}},{"name":"mode","type":"string","required":false,"default":"in_place","description":"in_place restarts tasks in the existing allocations; migrate stops them and schedules replacements.","validation":{"enum":["in_place","migrate"]}},{"name":"group","type":"string","required":false,"default":"","description":"Restrict the restart to one task group (empty = all groups).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"task","type":"string","required":false,"default":"","description":"Restrict the restart to one task (empty = running tasks; only valid with mode=in_place).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rolling in-place restart, one alloc at a time","args":{"job":"api"}},{"title":"Migrate a quarter of the allocs per batch","args":{"batch_size":"25%","job":"api","mode":"migrate"}}],"search_terms":["rolling restart"]},{"id":"nomad.job_revert","title":"nomad job revert <id> <version>","summary":"Revert a job to a prior version. Equivalent to re-submitting that version.","description":"Revert a job to a prior version. Equivalent to re-submitting that version.","kind":"script","risk":"high","side_effects":["Job spec replaced with the prior version.","Triggers a rolling update (per the new/old spec's update stanza)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"version","type":"integer","required":true,"description":"Version number to revert to.","validation":{"min":0,"max":1000000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Roll back one version","args":{"job":"api","version":7}}],"search_terms":["rollback","roll back deployment","undo deploy","previous version"]},{"id":"nomad.job_scale","title":"nomad job scale <id> <group> <count>","summary":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","description":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","kind":"script","risk":"high","side_effects":["Scheduler creates or stops allocations to reach the target count.","Stopped allocations follow the kill_timeout / shutdown_delay stanzas."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"count","type":"integer","required":true,"description":"Target count.","validation":{"min":0,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Scale api group to 10","args":{"count":10,"group":"web","job":"api"}}],"search_terms":["scale up","scale down","more replicas"]},{"id":"nomad.job_start","title":"nomad job start <id>","summary":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","description":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","kind":"script","risk":"medium","side_effects":["A new job version is created and its allocations are scheduled.","Workload that was deliberately stopped starts running again."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID of a stopped (not purged) job.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Start a stopped job","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_status_all","title":"nomad job status (all)","summary":"List all jobs with their type, priority, status, and submit time.","description":"List all jobs with their type, priority, status, and submit time.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All jobs","args":{}},{"title":"All jobs in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_status_one","title":"nomad job status <id>","summary":"Show one job's full status — task groups, allocations, deployment.","description":"Show one job's full status — task groups, allocations, deployment.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One job","args":{"job":"api"}},{"title":"One job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["pods restarting","crash loop","tasks flapping"]},{"id":"nomad.job_stop","title":"nomad job stop <id>","summary":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","description":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","kind":"script","risk":"high","side_effects":["All allocations of the job receive a shutdown signal.","Job marked dead in catalog.","History retained unless --purge is used (this action does NOT purge)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stop one job","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address (host:port).","description":"Show the current Raft leader address (host:port).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/status/leader"]}},{"id":"nomad.namespace_list","title":"nomad namespace list","summary":"List all namespaces in the cluster.","description":"List all namespaces in the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["namespace","list"]}},{"id":"nomad.node_drain","title":"nomad node drain -enable","summary":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","description":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","kind":"exec","risk":"high","side_effects":["Node stops accepting new allocations.","Existing allocations are migrated according to job spec (Migrate stanza).","May take minutes to complete depending on workload."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"deadline","type":"string","required":false,"default":"1h","description":"Force-eject after this duration if migration hasn't completed.","validation":{"pattern":"^[0-9]{1,4}[smh]$"}}],"examples":[{"title":"Drain one client","args":{"node_id":"abc12345"}}],"search_terms":["evacuate node","host maintenance"],"command":{"binary":"nomad","argv":["node","drain","-enable","-deadline","{{ args.deadline }}","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_drain_done","title":"nomad node drain -disable","summary":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","description":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","kind":"exec","risk":"medium","side_effects":["Drain mode disabled.","Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"End drain","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","drain","-disable","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_disable","title":"nomad node eligibility -disable","summary":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","description":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","kind":"exec","risk":"high","side_effects":["Node refuses new allocations.","Existing allocations stay running."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Cordon one","args":{"node_id":"abc12345"}}],"search_terms":["cordon","mark unschedulable"],"command":{"binary":"nomad","argv":["node","eligibility","-disable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_enable","title":"nomad node eligibility -enable","summary":"Re-enable a node for new allocations.","description":"Re-enable a node for new allocations.","kind":"exec","risk":"medium","side_effects":["Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Uncordon","args":{"node_id":"abc12345"}}],"search_terms":["uncordon"],"command":{"binary":"nomad","argv":["node","eligibility","-enable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_show","title":"Nodes with eligibility != eligible","summary":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","description":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Ineligible nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nomad node status -filter 'SchedulingEligibility != \"eligible\"'"]}},{"id":"nomad.node_pool_jobs","title":"nomad node pool jobs <pool>","summary":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","description":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Jobs in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_pool_list","title":"nomad node pool list","summary":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","description":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All node pools","args":{}}],"search_terms":[]},{"id":"nomad.node_pool_nodes","title":"nomad node pool nodes <pool>","summary":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","description":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Nodes in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_purge","title":"Purge a dead node (PUT /v1/node/<id>/purge)","summary":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","description":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","kind":"exec","risk":"critical","side_effects":["Node entry removed permanently (one API PUT).","Allocations on it are GC'd.","Only valid for nodes that are down — running nodes refuse purge."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Purge a dead node","args":{"node_id":"deadbeef"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","-X","PUT","/v1/node/{{ args.node_id }}/purge"]}},{"id":"nomad.node_status_all","title":"nomad node status","summary":"List all clients (nodes) with status, datacenter, drain state, eligibility.","description":"List all clients (nodes) with status, datacenter, drain state, eligibility.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster nodes","args":{}}],"search_terms":["node down","lost node"],"command":{"binary":"nomad","argv":["node","status","-verbose"]}},{"id":"nomad.node_status_one","title":"nomad node status <id>","summary":"Show one node's full detail — resources, allocations, events, drivers.","description":"Show one node's full detail — resources, allocations, events, drivers.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"One node","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","status","-verbose","{{ args.node_id }}"]}},{"id":"nomad.operator_autopilot_get_config","title":"nomad operator autopilot get-config","summary":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","description":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","autopilot","get-config"]}},{"id":"nomad.operator_autopilot_state","title":"GET /v1/operator/autopilot/health","summary":"Show the autopilot health view — leader health, follower lag, server stabilization.","description":"Show the autopilot health view — leader health, follower lag, server stabilization.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/operator/autopilot/health"]}},{"id":"nomad.operator_raft_list_peers","title":"nomad operator raft list-peers","summary":"List the Raft peers — voter status, suffrage, address.","description":"List the Raft peers — voter status, suffrage, address.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","list-peers"]}},{"id":"nomad.operator_raft_remove_peer","title":"nomad operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:4647"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","remove-peer","-peer-address","{{ args.address }}"]}},{"id":"nomad.operator_scheduler_get_config","title":"nomad operator scheduler get-config","summary":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","description":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster scheduler configuration","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","scheduler","get-config"]}},{"id":"nomad.plugin_status","title":"nomad plugin status [id]","summary":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","description":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"plugin_id","type":"string","required":false,"default":"","description":"Plugin ID or prefix (empty = list all plugins).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All CSI plugins","args":{}},{"title":"One plugin's health","args":{"plugin_id":"aws-ebs0"}}],"search_terms":["volume stuck","mount failing"]},{"id":"nomad.quota_list","title":"nomad quota list","summary":"List resource quotas (Enterprise feature).","description":"List resource quotas (Enterprise feature).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Quotas","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["quota","list"]}},{"id":"nomad.server_members","title":"nomad server members (json)","summary":"List the server members as JSON. Use for programmatic consumption.","description":"List the server members as JSON. Use for programmatic consumption.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members JSON","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/members"]}},{"id":"nomad.service_info","title":"nomad service info <name>","summary":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Registered service name (from nomad.service_list).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Instances of the \"redis\" service","args":{"service":"redis"}}],"search_terms":[]},{"id":"nomad.service_list","title":"nomad service list","summary":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","description":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All Nomad-registered services","args":{}},{"title":"Services in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.system_gc","title":"nomad system gc","summary":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","description":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","kind":"exec","risk":"medium","side_effects":["Old dead jobs/evals/allocs/deployments are removed from the catalog.","Frees Raft / state-store space."],"args":[],"examples":[{"title":"Trigger GC","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["system","gc"]}},{"id":"nomad.task_resources_set","title":"nomad job inspect | set task CPU/memory | job run","summary":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","description":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","kind":"script","risk":"high","side_effects":["Re-registers the job with the patched task resources (one read + one write API call).","Triggers a rolling update of the task group — allocations are replaced per its update stanza.","Setting memory below the task's real working set can cause OOM kills on the new allocations.","Refuses to write if the job changed since it was read (JobModifyIndex mismatch)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Task name. Empty selects the group's only task (errors if the group has more than one).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"cpu","type":"integer","required":false,"default":0,"description":"New CPU reservation in MHz. 0 leaves it unchanged.","validation":{"min":0,"max":1000000}},{"name":"memory","type":"integer","required":false,"default":0,"description":"New memory reservation (MemoryMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"memory_max","type":"integer","required":false,"default":0,"description":"New memory oversubscription cap (MemoryMaxMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Bump web/server to 1 vCPU + 1 GiB","args":{"cpu":1000,"group":"web","job":"api","memory":1024,"task":"server"}},{"title":"Raise memory only on a single-task group (auto-select)","args":{"group":"redis","job":"cache","memory":2048}}],"search_terms":["raise memory limit","bump cpu"]},{"id":"nomad.var_list","title":"nomad var list [prefix]","summary":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","description":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Values are never fetched — metadata only."],"args":[{"name":"prefix","type":"string","required":false,"default":"","description":"Path prefix to restrict the listing (empty = all variables).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_/.\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All variable paths","args":{}},{"title":"Variables under nomad/jobs","args":{"prefix":"nomad/jobs"}}],"search_terms":[]}],"previous_versions":[{"version":"0.4.2","content_hash":"sha256:924728440a3b79ce5cc0e37e347f72ca051bd325b759e962a9d34d120f38de4b","tarball_url":"https://registry.emisar.dev/v1/packs/nomad/0.4.2/924728440a3b79ce5cc0e37e347f72ca051bd325b759e962a9d34d120f38de4b/pack.tar.gz","actions":[{"id":"nomad.acl_policies","title":"nomad acl policy list","summary":"List all ACL policy names.","description":"List all ACL policy names.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","policy","list"]}},{"id":"nomad.acl_token_self","title":"nomad acl token self","summary":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","description":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only; the Secret ID field printed by the CLI is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","token","self"]}},{"id":"nomad.agent_force_leave","title":"nomad server force-leave <node>","summary":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","description":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","kind":"exec","risk":"high","side_effects":["The named server is marked left in serf.","Raft membership unaffected — use operator raft remove-peer for that."],"args":[{"name":"node_name","type":"string","required":true,"description":"Server node name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Force one server out","args":{"node_name":"nomad-server-3"}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","force-leave","{{ args.node_name }}"]}},{"id":"nomad.agent_info","title":"nomad agent-info","summary":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","description":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent info","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["agent-info"]}},{"id":"nomad.agent_members","title":"nomad server members","summary":"List the Serf gossip pool members.","description":"List the Serf gossip pool members.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","members","-detailed"]}},{"id":"nomad.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config (member name, region, datacenter, tags).","description":"Show this agent's effective config (member name, region, datacenter, tags).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Self config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/self"]}},{"id":"nomad.alloc_checks","title":"nomad alloc checks <id>","summary":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Health checks for one alloc","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_info","title":"Show Redis INFO inside an allocation (nomad alloc exec redis-cli info)","summary":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum.","description":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.info when you can reach it directly. The command is fixed except the enum section — no freeform command, shell, host, port, or password is accepted, so it reads the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance. risk:medium, not low: `nomad alloc exec` runs inside the running container and INFO exposes memory/stats/ replication topology, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/ raw-driver tasks).","kind":"script","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli info <section>` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"section","type":"string","required":false,"default":"default","description":"INFO section (bounded enum).","validation":{"enum":["default","all","server","clients","memory","persistence","stats","replication","cpu","commandstats","latencystats","cluster","keyspace","errorstats"]}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Default INFO of Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}},{"title":"Replication topology","args":{"alloc_id":"abc12345","section":"replication","task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_ping","title":"Ping Redis inside an allocation (nomad alloc exec redis-cli ping)","summary":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG.","description":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.ping when you can reach it directly. The command is fixed — no freeform command, shell, host, port, or password is accepted, so it connects to the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance (itself a signal). risk:medium, not low: `nomad alloc exec` runs inside the running container and can expose internal state, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/raw-driver tasks).","kind":"script","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli ping` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Ping Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_fs_ls","title":"List a directory in an allocation (nomad fs/ls API)","summary":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime.","description":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime. This is the \"what files did my task write to local/ or alloc/logs\" read for debugging, with no local CLI session. It calls Nomad's fs/ls API endpoint, which returns directory metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path defaults to the alloc root (/), is relative to it (Nomad contains it to the alloc dir), and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only (directory metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":false,"default":"/","description":"Directory to list, relative to the alloc root (e.g. local, alloc/logs, secrets). Defaults to the alloc root \"/\". No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"List the alloc root","args":{"alloc_id":"abc12345"}},{"title":"List the task's local/ directory","args":{"alloc_id":"abc12345","path":"local"}}],"search_terms":[]},{"id":"nomad.alloc_fs_stat","title":"Stat a path in an allocation (nomad fs/stat API)","summary":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type.","description":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type. This is the \"does this file exist / how big is it / when was it written\" read. It calls Nomad's fs/stat API endpoint, which returns metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path is relative to the alloc root (Nomad contains it to the alloc dir) and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only (file metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"Path to stat, relative to the alloc root (e.g. local/app.log, secrets/.env). No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stat a task's log file","args":{"alloc_id":"abc12345","path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_fs_tail","title":"Tail a file inside an allocation (nomad alloc fs -tail)","summary":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say.","description":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say. Unlike nomad.alloc_logs, which returns a task's stdout or stderr stream, this reads a FILE the task wrote. It is medium rather than low because a rendered template can hold whatever the job author put in it, so the content is not knowable from the action alone. Two bounds keep that honest — path rejects the secrets/ tree outright, and lines is capped — but neither can vouch for a file this action has never seen; treat the tier as the promise and the redaction as a backstop. Requires a Nomad token with read-fs on the namespace.","kind":"script","risk":"medium","side_effects":["One API call through the Nomad CLI.","Read-only; nothing in the allocation is modified.","Returns file CONTENT, unlike alloc_fs_ls and alloc_fs_stat which return metadata only. A file a job author rendered may contain anything they put in it.","The packaged script refuses the secrets/ tree before calling nomad, so Nomad's own rendered-credential mount cannot be read through this action."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"File to tail, relative to the alloc root (e.g. local/config.json, alloc/logs/app.stdout.0). The secrets/ tree is rejected — that is where Nomad mounts rendered credentials. No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*$","max_length":256}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many trailing lines to return.","validation":{"min":1,"max":500}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}}],"examples":[{"title":"Tail a rendered config file","args":{"alloc_id":"abc12345","path":"local/config.json"}},{"title":"Last 20 lines of a task's log file","args":{"alloc_id":"abc12345","lines":20,"path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_list_by_meta","title":"List allocations by job meta (GET /v1/allocations?filter=Job.Meta[…])","summary":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","description":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all allocations).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All allocations (compact)","args":{}},{"title":"Allocations of terraform-managed jobs","args":{"meta_key":"managed_by","meta_value":"terraform"}}],"search_terms":[]},{"id":"nomad.alloc_logs","title":"Tail a task's application logs — stdout (nomad alloc logs)","summary":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout.","description":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout. This is the read for \"show me the app logs\" or \"tail the service output\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs_stderr for the stderr stream (errors, stack traces, panics).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stdout lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stdout lines while chasing a restart","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_logs_stderr","title":"Tail a task's application logs — stderr (nomad alloc logs -stderr)","summary":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output).","description":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output). This is the read for \"show me the error logs\" or \"why did it crash\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs for the stdout stream.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stderr lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stderr lines after a crash","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_restart","title":"nomad alloc restart <id> [task]","summary":"Restart one task (or all tasks if not specified) in one allocation.","description":"Restart one task (or all tasks if not specified) in one allocation.","kind":"exec","risk":"high","side_effects":["Task(s) receive SIGTERM then SIGKILL after kill_timeout.","In-flight requests drop unless shutdown_delay is set."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all tasks).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Restart one task","args":{"alloc_id":"abc12345","task":"web"}}],"search_terms":["restart pod","bounce task"],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; task=$2; alloc=$3; set -- alloc restart; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; [ -z \"$task\" ] || set -- \"$@\" -task \"$task\"; exec nomad \"$@\" \"$alloc\"","emisar","{{ args.namespace }}","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_signal","title":"nomad alloc signal -s <signal> <id> [task]","summary":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","description":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","kind":"exec","risk":"high","side_effects":["Targeted task(s) receive the signal.","Effect depends on the application's signal handling."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"signal","type":"string","required":true,"description":"Signal name (HUP, USR1, USR2, etc).","validation":{"enum":["HUP","USR1","USR2","INT","TERM","QUIT"]}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"SIGHUP to reload","args":{"alloc_id":"abc12345","signal":"HUP","task":"web"}}],"search_terms":["send sighup","reload config"],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; task=$2; alloc=$3; set -- alloc signal -s {{ args.signal }}; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; [ -z \"$task\" ] || set -- \"$@\" -task \"$task\"; exec nomad \"$@\" \"$alloc\"","emisar","{{ args.namespace }}","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_stats","title":"GET /v1/client/allocation/<id>/stats","summary":"Show CPU + memory + network stats for one allocation.","description":"Show CPU + memory + network stats for one allocation.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stats","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_status","title":"nomad alloc status <id>","summary":"Show one allocation's full state — task states, restarts, last events.","description":"Show one allocation's full state — task states, restarts, last events.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One alloc","args":{"alloc_id":"abc12345"}},{"title":"One alloc in the \"prod\" namespace","args":{"alloc_id":"abc12345","namespace":"prod"}}],"search_terms":["crash loop","tasks flapping","oom killed","restart loop"]},{"id":"nomad.alloc_stop","title":"nomad alloc stop <id>","summary":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","description":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","kind":"script","risk":"high","side_effects":["Allocation is stopped + replaced.","Brief unavailability for the running container."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force-reschedule","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.csi_volume_list","title":"nomad volume status","summary":"List all registered CSI volumes with claim count + state.","description":"List all registered CSI volumes with claim count + state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"CSI volumes","args":{}},{"title":"CSI volumes in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.csi_volume_status","title":"nomad volume status <id>","summary":"Show one CSI volume's full state — claims, allocations using it, plugin status.","description":"Show one CSI volume's full state — claims, allocations using it, plugin status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"volume_id","type":"string","required":true,"description":"Volume ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"One volume","args":{"volume_id":"data-volume-1"}},{"title":"One volume in the \"prod\" namespace","args":{"namespace":"prod","volume_id":"data-volume-1"}}],"search_terms":[]},{"id":"nomad.deployment_fail","title":"nomad deployment fail <id>","summary":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","description":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","kind":"script","risk":"high","side_effects":["The rollout stops; no further canaries or placements from this deployment.","With auto_revert, the job rolls back to its last stable version."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Abort a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":["abort rollout","cancel deployment"]},{"id":"nomad.deployment_list","title":"nomad deployment list","summary":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","description":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All deployments","args":{}},{"title":"Deployments in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":["deploy stuck","rollout stalled"]},{"id":"nomad.deployment_pause","title":"nomad deployment pause <id>","summary":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","description":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","kind":"script","risk":"medium","side_effects":["No further placements from this deployment until resumed."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Pause a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.deployment_resume","title":"nomad deployment resume <id>","summary":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","description":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","kind":"script","risk":"medium","side_effects":["The rollout continues; new allocations are placed per the update stanza."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Resume a paused rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.deployment_status","title":"nomad deployment status <id>","summary":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","description":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Deployment status","args":{"deployment_id":"abc12345"}}],"search_terms":["deploy stuck","rollout stalled","deploy failing"]},{"id":"nomad.eval_list","title":"nomad eval list","summary":"List all recent evaluations across the cluster.","description":"List all recent evaluations across the cluster.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Recent evals","args":{}},{"title":"Recent evals in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.eval_status","title":"nomad eval status <id>","summary":"Show one evaluation's status — placement failures, queued allocations, blocked count.","description":"Show one evaluation's status — placement failures, queued allocations, blocked count.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"eval_id","type":"string","required":true,"description":"Evaluation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Eval status","args":{"eval_id":"abc12345"}}],"search_terms":["stuck pending","not scheduling"]},{"id":"nomad.event_snapshot","title":"Snapshot recent Nomad events (bounded /v1/event/stream)","summary":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session.","description":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session. Nomad has no \"last N events\" query: /v1/event/stream is a forward feed whose only history is the broker's replay buffer (~100 events). This reads it from index=1 (replays the buffer, then live events) for `seconds` seconds, capped at 256 KiB, then returns — so it never hangs. Optionally filter to one `topic` or one `namespace`. Output is NDJSON: one {Index, Events:[...]} batch per line. Requires a token that can read the event stream.","kind":"script","risk":"low","side_effects":["Opens the Nomad event stream for a bounded time window.","Read-only."],"args":[{"name":"seconds","type":"integer","required":false,"default":5,"description":"How long to read the stream — the snapshot window, in seconds.","validation":{"min":1,"max":15}},{"name":"topic","type":"string","required":false,"default":"","description":"Filter to one event topic (empty = all topics). One of Job, Allocation, Evaluation, Deployment, Node, Service, or an ACL topic.","validation":{"pattern":"^(Job|Allocation|Evaluation|Deployment|Node|Service|ACLToken|ACLPolicy|ACLRole|ACLAuthMethod|ACLBindingRule|NodePool)?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Filter to one namespace (empty = the runner's ambient/default).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_-]{0,127})?$"}}],"examples":[{"title":"Recent events across all topics (5s window)","args":{}},{"title":"Recent allocation events only","args":{"topic":"Allocation"}},{"title":"Recent events in one namespace, 10s window","args":{"namespace":"production","seconds":10}}],"search_terms":[]},{"id":"nomad.host_volume_list","title":"Host volumes from /v1/nodes","summary":"List host-volume declarations across all client nodes.","description":"List host-volume declarations across all client nodes.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host volumes","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/nodes"]}},{"id":"nomad.job_action_run","title":"nomad action -job <job> -group <group> -task <task> <name>","summary":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+).","description":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+). Nomad job authors declare named commands in the task's `action` blocks; this executes ONE of them by name — whatever command the job spec declares, with the task's own environment and filesystem. The pack fixes nothing about the command itself, so treat this as remote execution bounded by the job author, not by this pack. List a job's declared actions via nomad.job_inspect (TaskGroups[].Tasks[].Actions). Requires a token with alloc-exec.","kind":"script","risk":"high","side_effects":["The job-defined command runs inside the task's container/environment.","Effect depends entirely on what the job author declared."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"action_name","type":"string","required":true,"description":"The action name declared in the job spec's `action` block.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Run a job-declared action","args":{"action_name":"reload-config","group":"web","job":"api","task":"app"}}],"search_terms":[]},{"id":"nomad.job_allocations","title":"nomad job allocs <id>","summary":"List all allocations for one job.","description":"List all allocations for one job.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Allocations","args":{"job":"api"}},{"title":"Allocations in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_deployments","title":"nomad job deployments <id>","summary":"List deployment history for one job (rolling updates, canary, blue-green).","description":"List deployment history for one job (rolling updates, canary, blue-green).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Deployments","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_dispatch","title":"nomad job dispatch <id>","summary":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","description":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","kind":"exec","risk":"high","side_effects":["A new dispatched job instance is created and scheduled.","Counts toward job history."],"args":[{"name":"job","type":"string","required":true,"description":"Parameterized job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"meta_kv","type":"string","required":false,"default":"","description":"Optional meta as 'k=v,k2=v2' (no spaces around =).","validation":{"pattern":"^([a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256}(,[a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256})*)?$","max_length":1024}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Dispatch with meta","args":{"job":"batch-processor","meta_kv":"input=/tmp/data,priority=high"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; meta=$2; job=$3; set -- job dispatch; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; if [ -n \"$meta\" ]; then oldifs=$IFS; IFS=,; for kv in $meta; do set -- \"$@\" -meta \"$kv\"; done; IFS=$oldifs; fi; exec nomad \"$@\" \"$job\"","emisar","{{ args.namespace }}","{{ args.meta_kv }}","{{ args.job }}"]}},{"id":"nomad.job_eval","title":"nomad job eval <id>","summary":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","description":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","kind":"exec","risk":"medium","side_effects":["A new evaluation is created; the scheduler may place or reschedule allocations."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"force_reschedule","type":"string","required":false,"default":"false","description":"true also reschedules failed allocations that are past their reschedule limit.","validation":{"enum":["false","true"]}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Re-evaluate a job","args":{"job":"api"}},{"title":"Force failed allocs to reschedule","args":{"force_reschedule":"true","job":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; job=$2; force=$3; set -- job eval -detach; [ \"$force\" = true ] && set -- \"$@\" -force-reschedule; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; exec nomad \"$@\" -- \"$job\"","emisar","{{ args.namespace }}","{{ args.job }}","{{ args.force_reschedule }}"]}},{"id":"nomad.job_evaluations","title":"nomad job eval <id> (force re-evaluation)","summary":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","description":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","kind":"script","risk":"medium","side_effects":["Creates a new evaluation for the job.","The scheduler reconciles the job; allocations may be moved or restarted."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force a re-evaluation","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_health_snapshot","title":"Nomad job health snapshot","summary":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","description":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","kind":"script","risk":"low","side_effects":["Four fixed read-only Nomad API calls plus one checks read per returned allocation.","Allocation and event counts are bounded by validated arguments.","Read-only - never changes a job, deployment, allocation, or check."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty keeps the runner's ambient namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty keeps the runner's ambient region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}},{"name":"allocation_limit","type":"integer","required":false,"default":10,"description":"Maximum recent allocations and associated check reads.","validation":{"min":1,"max":25}},{"name":"events_per_task","type":"integer","required":false,"default":5,"description":"Maximum recent restart and failed events retained per task.","validation":{"min":1,"max":20}}],"examples":[{"title":"Recent health for an API job","args":{"job":"api"}},{"title":"Smaller production snapshot","args":{"allocation_limit":5,"events_per_task":3,"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_history","title":"nomad job history <id>","summary":"List all versions of one job with submitter + timestamp.","description":"List all versions of one job with submitter + timestamp.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"History","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_inspect","title":"nomad job inspect <id>","summary":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"script","risk":"high","side_effects":["One API call.","Read-only, but exposes the job's env/template blocks (may include secrets)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Inspect job","args":{"job":"api"}},{"title":"Inspect a job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["jobspec","job definition"]},{"id":"nomad.job_list_by_meta","title":"List jobs with meta (GET /v1/jobs?meta=true [&filter])","summary":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","description":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all jobs).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All jobs with their meta","args":{}},{"title":"Jobs managed by Terraform","args":{"meta_key":"managed_by","meta_value":"terraform"}},{"title":"One application's jobs across all namespaces","args":{"meta_key":"application","meta_value":"blitz-website","namespace":"*"}}],"search_terms":[]},{"id":"nomad.job_periodic_force","title":"nomad job periodic force <id>","summary":"Force-run one periodic job NOW, ignoring schedule.","description":"Force-run one periodic job NOW, ignoring schedule.","kind":"script","risk":"medium","side_effects":["A new periodic child job is created and dispatched.","Counts toward normal job history."],"args":[{"name":"job","type":"string","required":true,"description":"Periodic job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force-run","args":{"job":"nightly-backup"}}],"search_terms":["run cron now","trigger scheduled job"]},{"id":"nomad.job_promote","title":"nomad job promote <id>","summary":"Promote a canary deployment — replaces the rest of the allocations with the new version.","description":"Promote a canary deployment — replaces the rest of the allocations with the new version.","kind":"script","risk":"high","side_effects":["Old allocations are gradually replaced per the update stanza.","In-flight requests on replaced allocs may drop (subject to shutdown_delay)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID with an in-progress canary.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Promote canary","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_resources","title":"nomad job inspect <id> (resource summary)","summary":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","description":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","kind":"script","risk":"low","side_effects":["One read-only API call (job inspect).","Read-only — never writes or mutates job state."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Show current resources per group/task","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_restart","title":"nomad job restart <id>","summary":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","description":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","kind":"script","risk":"high","side_effects":["Every targeted task is stopped and started again, batch by batch.","In-flight requests on restarting allocs may drop (subject to shutdown_delay).","mode=migrate reschedules allocations, possibly onto different nodes."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"batch_size","type":"string","required":false,"default":"1","description":"Allocations per batch — a count (\"2\") or a percentage of running allocs (\"25%\").","validation":{"pattern":"^[1-9][0-9]{0,3}%?$"}},{"name":"mode","type":"string","required":false,"default":"in_place","description":"in_place restarts tasks in the existing allocations; migrate stops them and schedules replacements.","validation":{"enum":["in_place","migrate"]}},{"name":"group","type":"string","required":false,"default":"","description":"Restrict the restart to one task group (empty = all groups).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"task","type":"string","required":false,"default":"","description":"Restrict the restart to one task (empty = running tasks; only valid with mode=in_place).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rolling in-place restart, one alloc at a time","args":{"job":"api"}},{"title":"Migrate a quarter of the allocs per batch","args":{"batch_size":"25%","job":"api","mode":"migrate"}}],"search_terms":["rolling restart"]},{"id":"nomad.job_revert","title":"nomad job revert <id> <version>","summary":"Revert a job to a prior version. Equivalent to re-submitting that version.","description":"Revert a job to a prior version. Equivalent to re-submitting that version.","kind":"script","risk":"high","side_effects":["Job spec replaced with the prior version.","Triggers a rolling update (per the new/old spec's update stanza)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"version","type":"integer","required":true,"description":"Version number to revert to.","validation":{"min":0,"max":1000000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Roll back one version","args":{"job":"api","version":7}}],"search_terms":["rollback","roll back deployment","undo deploy","previous version"]},{"id":"nomad.job_scale","title":"nomad job scale <id> <group> <count>","summary":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","description":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","kind":"script","risk":"high","side_effects":["Scheduler creates or stops allocations to reach the target count.","Stopped allocations follow the kill_timeout / shutdown_delay stanzas."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"count","type":"integer","required":true,"description":"Target count.","validation":{"min":0,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Scale api group to 10","args":{"count":10,"group":"web","job":"api"}}],"search_terms":["scale up","scale down","more replicas"]},{"id":"nomad.job_start","title":"nomad job start <id>","summary":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","description":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","kind":"script","risk":"medium","side_effects":["A new job version is created and its allocations are scheduled.","Workload that was deliberately stopped starts running again."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID of a stopped (not purged) job.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Start a stopped job","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_status_all","title":"nomad job status (all)","summary":"List all jobs with their type, priority, status, and submit time.","description":"List all jobs with their type, priority, status, and submit time.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All jobs","args":{}},{"title":"All jobs in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_status_one","title":"nomad job status <id>","summary":"Show one job's full status — task groups, allocations, deployment.","description":"Show one job's full status — task groups, allocations, deployment.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One job","args":{"job":"api"}},{"title":"One job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["pods restarting","crash loop","tasks flapping"]},{"id":"nomad.job_stop","title":"nomad job stop <id>","summary":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","description":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","kind":"script","risk":"high","side_effects":["All allocations of the job receive a shutdown signal.","Job marked dead in catalog.","History retained unless --purge is used (this action does NOT purge)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stop one job","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address (host:port).","description":"Show the current Raft leader address (host:port).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/status/leader"]}},{"id":"nomad.namespace_list","title":"nomad namespace list","summary":"List all namespaces in the cluster.","description":"List all namespaces in the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["namespace","list"]}},{"id":"nomad.node_drain","title":"nomad node drain -enable","summary":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","description":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","kind":"exec","risk":"high","side_effects":["Node stops accepting new allocations.","Existing allocations are migrated according to job spec (Migrate stanza).","May take minutes to complete depending on workload."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"deadline","type":"string","required":false,"default":"1h","description":"Force-eject after this duration if migration hasn't completed.","validation":{"pattern":"^[0-9]{1,4}[smh]$"}}],"examples":[{"title":"Drain one client","args":{"node_id":"abc12345"}}],"search_terms":["evacuate node","host maintenance"],"command":{"binary":"nomad","argv":["node","drain","-enable","-deadline","{{ args.deadline }}","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_drain_done","title":"nomad node drain -disable","summary":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","description":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","kind":"exec","risk":"medium","side_effects":["Drain mode disabled.","Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"End drain","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","drain","-disable","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_disable","title":"nomad node eligibility -disable","summary":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","description":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","kind":"exec","risk":"high","side_effects":["Node refuses new allocations.","Existing allocations stay running."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Cordon one","args":{"node_id":"abc12345"}}],"search_terms":["cordon","mark unschedulable"],"command":{"binary":"nomad","argv":["node","eligibility","-disable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_enable","title":"nomad node eligibility -enable","summary":"Re-enable a node for new allocations.","description":"Re-enable a node for new allocations.","kind":"exec","risk":"medium","side_effects":["Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Uncordon","args":{"node_id":"abc12345"}}],"search_terms":["uncordon"],"command":{"binary":"nomad","argv":["node","eligibility","-enable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_show","title":"Nodes with eligibility != eligible","summary":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","description":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Ineligible nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nomad node status -filter 'SchedulingEligibility != \"eligible\"'"]}},{"id":"nomad.node_pool_jobs","title":"nomad node pool jobs <pool>","summary":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","description":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Jobs in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_pool_list","title":"nomad node pool list","summary":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","description":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All node pools","args":{}}],"search_terms":[]},{"id":"nomad.node_pool_nodes","title":"nomad node pool nodes <pool>","summary":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","description":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Nodes in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_purge","title":"Purge a dead node (PUT /v1/node/<id>/purge)","summary":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","description":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","kind":"exec","risk":"critical","side_effects":["Node entry removed permanently (one API PUT).","Allocations on it are GC'd.","Only valid for nodes that are down — running nodes refuse purge."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Purge a dead node","args":{"node_id":"deadbeef"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","-X","PUT","/v1/node/{{ args.node_id }}/purge"]}},{"id":"nomad.node_status_all","title":"nomad node status","summary":"List all clients (nodes) with status, datacenter, drain state, eligibility.","description":"List all clients (nodes) with status, datacenter, drain state, eligibility.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster nodes","args":{}}],"search_terms":["node down","lost node"],"command":{"binary":"nomad","argv":["node","status","-verbose"]}},{"id":"nomad.node_status_one","title":"nomad node status <id>","summary":"Show one node's full detail — resources, allocations, events, drivers.","description":"Show one node's full detail — resources, allocations, events, drivers.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"One node","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","status","-verbose","{{ args.node_id }}"]}},{"id":"nomad.operator_autopilot_get_config","title":"nomad operator autopilot get-config","summary":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","description":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","autopilot","get-config"]}},{"id":"nomad.operator_autopilot_state","title":"GET /v1/operator/autopilot/health","summary":"Show the autopilot health view — leader health, follower lag, server stabilization.","description":"Show the autopilot health view — leader health, follower lag, server stabilization.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/operator/autopilot/health"]}},{"id":"nomad.operator_raft_list_peers","title":"nomad operator raft list-peers","summary":"List the Raft peers — voter status, suffrage, address.","description":"List the Raft peers — voter status, suffrage, address.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","list-peers"]}},{"id":"nomad.operator_raft_remove_peer","title":"nomad operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:4647"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","remove-peer","-peer-address","{{ args.address }}"]}},{"id":"nomad.operator_scheduler_get_config","title":"nomad operator scheduler get-config","summary":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","description":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster scheduler configuration","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","scheduler","get-config"]}},{"id":"nomad.plugin_status","title":"nomad plugin status [id]","summary":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","description":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"plugin_id","type":"string","required":false,"default":"","description":"Plugin ID or prefix (empty = list all plugins).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All CSI plugins","args":{}},{"title":"One plugin's health","args":{"plugin_id":"aws-ebs0"}}],"search_terms":["volume stuck","mount failing"]},{"id":"nomad.quota_list","title":"nomad quota list","summary":"List resource quotas (Enterprise feature).","description":"List resource quotas (Enterprise feature).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Quotas","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["quota","list"]}},{"id":"nomad.server_members","title":"nomad server members (json)","summary":"List the server members as JSON. Use for programmatic consumption.","description":"List the server members as JSON. Use for programmatic consumption.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members JSON","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/members"]}},{"id":"nomad.service_info","title":"nomad service info <name>","summary":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Registered service name (from nomad.service_list).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Instances of the \"redis\" service","args":{"service":"redis"}}],"search_terms":[]},{"id":"nomad.service_list","title":"nomad service list","summary":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","description":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All Nomad-registered services","args":{}},{"title":"Services in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.system_gc","title":"nomad system gc","summary":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","description":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","kind":"exec","risk":"medium","side_effects":["Old dead jobs/evals/allocs/deployments are removed from the catalog.","Frees Raft / state-store space."],"args":[],"examples":[{"title":"Trigger GC","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["system","gc"]}},{"id":"nomad.task_resources_set","title":"nomad job inspect | set task CPU/memory | job run","summary":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","description":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","kind":"script","risk":"high","side_effects":["Re-registers the job with the patched task resources (one read + one write API call).","Triggers a rolling update of the task group — allocations are replaced per its update stanza.","Setting memory below the task's real working set can cause OOM kills on the new allocations.","Refuses to write if the job changed since it was read (JobModifyIndex mismatch)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Task name. Empty selects the group's only task (errors if the group has more than one).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"cpu","type":"integer","required":false,"default":0,"description":"New CPU reservation in MHz. 0 leaves it unchanged.","validation":{"min":0,"max":1000000}},{"name":"memory","type":"integer","required":false,"default":0,"description":"New memory reservation (MemoryMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"memory_max","type":"integer","required":false,"default":0,"description":"New memory oversubscription cap (MemoryMaxMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Bump web/server to 1 vCPU + 1 GiB","args":{"cpu":1000,"group":"web","job":"api","memory":1024,"task":"server"}},{"title":"Raise memory only on a single-task group (auto-select)","args":{"group":"redis","job":"cache","memory":2048}}],"search_terms":["raise memory limit","bump cpu"]},{"id":"nomad.var_list","title":"nomad var list [prefix]","summary":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","description":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Values are never fetched — metadata only."],"args":[{"name":"prefix","type":"string","required":false,"default":"","description":"Path prefix to restrict the listing (empty = all variables).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_/.\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All variable paths","args":{}},{"title":"Variables under nomad/jobs","args":{"prefix":"nomad/jobs"}}],"search_terms":[]}]},{"version":"0.4.0","content_hash":"sha256:0febd1ebe61238abb245ac137a8d72b09a97dcb9ad3329b7b31e75b97d183e59","tarball_url":"https://registry.emisar.dev/v1/packs/nomad/0.4.0/0febd1ebe61238abb245ac137a8d72b09a97dcb9ad3329b7b31e75b97d183e59/pack.tar.gz","actions":[{"id":"nomad.acl_policies","title":"nomad acl policy list","summary":"List all ACL policy names.","description":"List all ACL policy names.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","policy","list"]}},{"id":"nomad.acl_token_self","title":"nomad acl token self","summary":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","description":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only; the Secret ID field printed by the CLI is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","token","self"]}},{"id":"nomad.agent_force_leave","title":"nomad server force-leave <node>","summary":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","description":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","kind":"exec","risk":"high","side_effects":["The named server is marked left in serf.","Raft membership unaffected — use operator raft remove-peer for that."],"args":[{"name":"node_name","type":"string","required":true,"description":"Server node name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Force one server out","args":{"node_name":"nomad-server-3"}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","force-leave","{{ args.node_name }}"]}},{"id":"nomad.agent_info","title":"nomad agent-info","summary":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","description":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent info","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["agent-info"]}},{"id":"nomad.agent_members","title":"nomad server members","summary":"List the Serf gossip pool members.","description":"List the Serf gossip pool members.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","members","-detailed"]}},{"id":"nomad.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config (member name, region, datacenter, tags).","description":"Show this agent's effective config (member name, region, datacenter, tags).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Self config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/self"]}},{"id":"nomad.alloc_checks","title":"nomad alloc checks <id>","summary":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Health checks for one alloc","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_info","title":"Show Redis INFO inside an allocation (nomad alloc exec redis-cli info)","summary":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum.","description":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.info when you can reach it directly. The command is fixed except the enum section — no freeform command, shell, host, port, or password is accepted, so it reads the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance. risk:medium, not low: `nomad alloc exec` runs inside the running container and INFO exposes memory/stats/ replication topology, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/ raw-driver tasks).","kind":"script","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli info <section>` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"section","type":"string","required":false,"default":"default","description":"INFO section (bounded enum).","validation":{"enum":["default","all","server","clients","memory","persistence","stats","replication","cpu","commandstats","latencystats","cluster","keyspace","errorstats"]}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Default INFO of Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}},{"title":"Replication topology","args":{"alloc_id":"abc12345","section":"replication","task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_ping","title":"Ping Redis inside an allocation (nomad alloc exec redis-cli ping)","summary":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG.","description":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.ping when you can reach it directly. The command is fixed — no freeform command, shell, host, port, or password is accepted, so it connects to the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance (itself a signal). risk:medium, not low: `nomad alloc exec` runs inside the running container and can expose internal state, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/raw-driver tasks).","kind":"script","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli ping` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Ping Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_fs_ls","title":"List a directory in an allocation (nomad fs/ls API)","summary":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime.","description":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime. This is the \"what files did my task write to local/ or alloc/logs\" read for debugging, with no local CLI session. It calls Nomad's fs/ls API endpoint, which returns directory metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path defaults to the alloc root (/), is relative to it (Nomad contains it to the alloc dir), and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only (directory metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":false,"default":"/","description":"Directory to list, relative to the alloc root (e.g. local, alloc/logs, secrets). Defaults to the alloc root \"/\". No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"List the alloc root","args":{"alloc_id":"abc12345"}},{"title":"List the task's local/ directory","args":{"alloc_id":"abc12345","path":"local"}}],"search_terms":[]},{"id":"nomad.alloc_fs_stat","title":"Stat a path in an allocation (nomad fs/stat API)","summary":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type.","description":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type. This is the \"does this file exist / how big is it / when was it written\" read. It calls Nomad's fs/stat API endpoint, which returns metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path is relative to the alloc root (Nomad contains it to the alloc dir) and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only (file metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"Path to stat, relative to the alloc root (e.g. local/app.log, secrets/.env). No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stat a task's log file","args":{"alloc_id":"abc12345","path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_fs_tail","title":"Tail a file inside an allocation (nomad alloc fs -tail)","summary":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say.","description":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say. Unlike nomad.alloc_logs, which returns a task's stdout or stderr stream, this reads a FILE the task wrote. It is medium rather than low because a rendered template can hold whatever the job author put in it, so the content is not knowable from the action alone. Two bounds keep that honest — path rejects the secrets/ tree outright, and lines is capped — but neither can vouch for a file this action has never seen; treat the tier as the promise and the redaction as a backstop. Requires a Nomad token with read-fs on the namespace.","kind":"script","risk":"medium","side_effects":["One API call through the Nomad CLI.","Read-only; nothing in the allocation is modified.","Returns file CONTENT, unlike alloc_fs_ls and alloc_fs_stat which return metadata only. A file a job author rendered may contain anything they put in it.","The packaged script refuses the secrets/ tree before calling nomad, so Nomad's own rendered-credential mount cannot be read through this action."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"File to tail, relative to the alloc root (e.g. local/config.json, alloc/logs/app.stdout.0). The secrets/ tree is rejected — that is where Nomad mounts rendered credentials. No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*$","max_length":256}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many trailing lines to return.","validation":{"min":1,"max":500}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}}],"examples":[{"title":"Tail a rendered config file","args":{"alloc_id":"abc12345","path":"local/config.json"}},{"title":"Last 20 lines of a task's log file","args":{"alloc_id":"abc12345","lines":20,"path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_list_by_meta","title":"List allocations by job meta (GET /v1/allocations?filter=Job.Meta[…])","summary":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","description":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all allocations).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All allocations (compact)","args":{}},{"title":"Allocations of terraform-managed jobs","args":{"meta_key":"managed_by","meta_value":"terraform"}}],"search_terms":[]},{"id":"nomad.alloc_logs","title":"Tail a task's application logs — stdout (nomad alloc logs)","summary":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout.","description":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout. This is the read for \"show me the app logs\" or \"tail the service output\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs_stderr for the stderr stream (errors, stack traces, panics).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stdout lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stdout lines while chasing a restart","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_logs_stderr","title":"Tail a task's application logs — stderr (nomad alloc logs -stderr)","summary":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output).","description":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output). This is the read for \"show me the error logs\" or \"why did it crash\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs for the stdout stream.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stderr lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stderr lines after a crash","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_restart","title":"nomad alloc restart <id> [task]","summary":"Restart one task (or all tasks if not specified) in one allocation.","description":"Restart one task (or all tasks if not specified) in one allocation.","kind":"exec","risk":"high","side_effects":["Task(s) receive SIGTERM then SIGKILL after kill_timeout.","In-flight requests drop unless shutdown_delay is set."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all tasks).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Restart one task","args":{"alloc_id":"abc12345","task":"web"}}],"search_terms":["restart pod","bounce task"],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; task=$2; alloc=$3; set -- alloc restart; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; [ -z \"$task\" ] || set -- \"$@\" -task \"$task\"; exec nomad \"$@\" \"$alloc\"","emisar","{{ args.namespace }}","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_signal","title":"nomad alloc signal -s <signal> <id> [task]","summary":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","description":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","kind":"exec","risk":"high","side_effects":["Targeted task(s) receive the signal.","Effect depends on the application's signal handling."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"signal","type":"string","required":true,"description":"Signal name (HUP, USR1, USR2, etc).","validation":{"enum":["HUP","USR1","USR2","INT","TERM","QUIT"]}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"SIGHUP to reload","args":{"alloc_id":"abc12345","signal":"HUP","task":"web"}}],"search_terms":["send sighup","reload config"],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; task=$2; alloc=$3; set -- alloc signal -s {{ args.signal }}; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; [ -z \"$task\" ] || set -- \"$@\" -task \"$task\"; exec nomad \"$@\" \"$alloc\"","emisar","{{ args.namespace }}","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_stats","title":"GET /v1/client/allocation/<id>/stats","summary":"Show CPU + memory + network stats for one allocation.","description":"Show CPU + memory + network stats for one allocation.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stats","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_status","title":"nomad alloc status <id>","summary":"Show one allocation's full state — task states, restarts, last events.","description":"Show one allocation's full state — task states, restarts, last events.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One alloc","args":{"alloc_id":"abc12345"}},{"title":"One alloc in the \"prod\" namespace","args":{"alloc_id":"abc12345","namespace":"prod"}}],"search_terms":["crash loop","tasks flapping","oom killed","restart loop"]},{"id":"nomad.alloc_stop","title":"nomad alloc stop <id>","summary":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","description":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","kind":"script","risk":"high","side_effects":["Allocation is stopped + replaced.","Brief unavailability for the running container."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force-reschedule","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.csi_volume_list","title":"nomad volume status","summary":"List all registered CSI volumes with claim count + state.","description":"List all registered CSI volumes with claim count + state.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"CSI volumes","args":{}},{"title":"CSI volumes in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.csi_volume_status","title":"nomad volume status <id>","summary":"Show one CSI volume's full state — claims, allocations using it, plugin status.","description":"Show one CSI volume's full state — claims, allocations using it, plugin status.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"volume_id","type":"string","required":true,"description":"Volume ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"One volume","args":{"volume_id":"data-volume-1"}},{"title":"One volume in the \"prod\" namespace","args":{"namespace":"prod","volume_id":"data-volume-1"}}],"search_terms":[]},{"id":"nomad.deployment_fail","title":"nomad deployment fail <id>","summary":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","description":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","kind":"script","risk":"high","side_effects":["The rollout stops; no further canaries or placements from this deployment.","With auto_revert, the job rolls back to its last stable version."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Abort a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":["abort rollout","cancel deployment"]},{"id":"nomad.deployment_list","title":"nomad deployment list","summary":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","description":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All deployments","args":{}},{"title":"Deployments in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":["deploy stuck","rollout stalled"]},{"id":"nomad.deployment_pause","title":"nomad deployment pause <id>","summary":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","description":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","kind":"script","risk":"medium","side_effects":["No further placements from this deployment until resumed."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Pause a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.deployment_resume","title":"nomad deployment resume <id>","summary":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","description":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","kind":"script","risk":"medium","side_effects":["The rollout continues; new allocations are placed per the update stanza."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Resume a paused rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.deployment_status","title":"nomad deployment status <id>","summary":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","description":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Deployment status","args":{"deployment_id":"abc12345"}}],"search_terms":["deploy stuck","rollout stalled","deploy failing"]},{"id":"nomad.eval_list","title":"nomad eval list","summary":"List all recent evaluations across the cluster.","description":"List all recent evaluations across the cluster.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Recent evals","args":{}},{"title":"Recent evals in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.eval_status","title":"nomad eval status <id>","summary":"Show one evaluation's status — placement failures, queued allocations, blocked count.","description":"Show one evaluation's status — placement failures, queued allocations, blocked count.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"eval_id","type":"string","required":true,"description":"Evaluation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Eval status","args":{"eval_id":"abc12345"}}],"search_terms":["stuck pending","not scheduling"]},{"id":"nomad.event_snapshot","title":"Snapshot recent Nomad events (bounded /v1/event/stream)","summary":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session.","description":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session. Nomad has no \"last N events\" query: /v1/event/stream is a forward feed whose only history is the broker's replay buffer (~100 events). This reads it from index=1 (replays the buffer, then live events) for `seconds` seconds, capped at 256 KiB, then returns — so it never hangs. Optionally filter to one `topic` or one `namespace`. Output is NDJSON: one {Index, Events:[...]} batch per line. Requires a token that can read the event stream.","kind":"script","risk":"low","side_effects":["Opens the Nomad event stream for a bounded time window.","Read-only."],"args":[{"name":"seconds","type":"integer","required":false,"default":5,"description":"How long to read the stream — the snapshot window, in seconds.","validation":{"min":1,"max":15}},{"name":"topic","type":"string","required":false,"default":"","description":"Filter to one event topic (empty = all topics). One of Job, Allocation, Evaluation, Deployment, Node, Service, or an ACL topic.","validation":{"pattern":"^(Job|Allocation|Evaluation|Deployment|Node|Service|ACLToken|ACLPolicy|ACLRole|ACLAuthMethod|ACLBindingRule|NodePool)?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Filter to one namespace (empty = the runner's ambient/default).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_-]{0,127})?$"}}],"examples":[{"title":"Recent events across all topics (5s window)","args":{}},{"title":"Recent allocation events only","args":{"topic":"Allocation"}},{"title":"Recent events in one namespace, 10s window","args":{"namespace":"production","seconds":10}}],"search_terms":[]},{"id":"nomad.host_volume_list","title":"Host volumes from /v1/nodes","summary":"List host-volume declarations across all client nodes.","description":"List host-volume declarations across all client nodes.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host volumes","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/nodes"]}},{"id":"nomad.job_action_run","title":"nomad action -job <job> -group <group> -task <task> <name>","summary":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+).","description":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+). Nomad job authors declare named commands in the task's `action` blocks; this executes ONE of them by name — whatever command the job spec declares, with the task's own environment and filesystem. The pack fixes nothing about the command itself, so treat this as remote execution bounded by the job author, not by this pack. List a job's declared actions via nomad.job_inspect (TaskGroups[].Tasks[].Actions). Requires a token with alloc-exec.","kind":"script","risk":"high","side_effects":["The job-defined command runs inside the task's container/environment.","Effect depends entirely on what the job author declared."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"action_name","type":"string","required":true,"description":"The action name declared in the job spec's `action` block.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Run a job-declared action","args":{"action_name":"reload-config","group":"web","job":"api","task":"app"}}],"search_terms":[]},{"id":"nomad.job_allocations","title":"nomad job allocs <id>","summary":"List all allocations for one job.","description":"List all allocations for one job.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Allocations","args":{"job":"api"}},{"title":"Allocations in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_deployments","title":"nomad job deployments <id>","summary":"List deployment history for one job (rolling updates, canary, blue-green).","description":"List deployment history for one job (rolling updates, canary, blue-green).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Deployments","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_dispatch","title":"nomad job dispatch <id>","summary":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","description":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","kind":"exec","risk":"high","side_effects":["A new dispatched job instance is created and scheduled.","Counts toward job history."],"args":[{"name":"job","type":"string","required":true,"description":"Parameterized job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"meta_kv","type":"string","required":false,"default":"","description":"Optional meta as 'k=v,k2=v2' (no spaces around =).","validation":{"pattern":"^([a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256}(,[a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256})*)?$","max_length":1024}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Dispatch with meta","args":{"job":"batch-processor","meta_kv":"input=/tmp/data,priority=high"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; meta=$2; job=$3; set -- job dispatch; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; if [ -n \"$meta\" ]; then oldifs=$IFS; IFS=,; for kv in $meta; do set -- \"$@\" -meta \"$kv\"; done; IFS=$oldifs; fi; exec nomad \"$@\" \"$job\"","emisar","{{ args.namespace }}","{{ args.meta_kv }}","{{ args.job }}"]}},{"id":"nomad.job_eval","title":"nomad job eval <id>","summary":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","description":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","kind":"exec","risk":"medium","side_effects":["A new evaluation is created; the scheduler may place or reschedule allocations."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"force_reschedule","type":"string","required":false,"default":"false","description":"true also reschedules failed allocations that are past their reschedule limit.","validation":{"enum":["false","true"]}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Re-evaluate a job","args":{"job":"api"}},{"title":"Force failed allocs to reschedule","args":{"force_reschedule":"true","job":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","ns=$1; job=$2; force=$3; set -- job eval -detach; [ \"$force\" = true ] && set -- \"$@\" -force-reschedule; [ -z \"$ns\" ] || set -- \"$@\" \"-namespace=$ns\"; exec nomad \"$@\" -- \"$job\"","emisar","{{ args.namespace }}","{{ args.job }}","{{ args.force_reschedule }}"]}},{"id":"nomad.job_evaluations","title":"nomad job eval <id> (force re-evaluation)","summary":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","description":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","kind":"script","risk":"medium","side_effects":["Creates a new evaluation for the job.","The scheduler reconciles the job; allocations may be moved or restarted."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force a re-evaluation","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_health_snapshot","title":"Nomad job health snapshot","summary":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","description":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","kind":"script","risk":"low","side_effects":["Four fixed read-only Nomad API calls plus one checks read per returned allocation.","Allocation and event counts are bounded by validated arguments.","Read-only - never changes a job, deployment, allocation, or check."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty keeps the runner's ambient namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty keeps the runner's ambient region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}},{"name":"allocation_limit","type":"integer","required":false,"default":10,"description":"Maximum recent allocations and associated check reads.","validation":{"min":1,"max":25}},{"name":"events_per_task","type":"integer","required":false,"default":5,"description":"Maximum recent restart and failed events retained per task.","validation":{"min":1,"max":20}}],"examples":[{"title":"Recent health for an API job","args":{"job":"api"}},{"title":"Smaller production snapshot","args":{"allocation_limit":5,"events_per_task":3,"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_history","title":"nomad job history <id>","summary":"List all versions of one job with submitter + timestamp.","description":"List all versions of one job with submitter + timestamp.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"History","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_inspect","title":"nomad job inspect <id>","summary":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"script","risk":"high","side_effects":["One API call.","Read-only, but exposes the job's env/template blocks (may include secrets)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Inspect job","args":{"job":"api"}},{"title":"Inspect a job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["jobspec","job definition"]},{"id":"nomad.job_list_by_meta","title":"List jobs with meta (GET /v1/jobs?meta=true [&filter])","summary":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","description":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all jobs).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All jobs with their meta","args":{}},{"title":"Jobs managed by Terraform","args":{"meta_key":"managed_by","meta_value":"terraform"}},{"title":"One application's jobs across all namespaces","args":{"meta_key":"application","meta_value":"blitz-website","namespace":"*"}}],"search_terms":[]},{"id":"nomad.job_periodic_force","title":"nomad job periodic force <id>","summary":"Force-run one periodic job NOW, ignoring schedule.","description":"Force-run one periodic job NOW, ignoring schedule.","kind":"script","risk":"medium","side_effects":["A new periodic child job is created and dispatched.","Counts toward normal job history."],"args":[{"name":"job","type":"string","required":true,"description":"Periodic job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Force-run","args":{"job":"nightly-backup"}}],"search_terms":["run cron now","trigger scheduled job"]},{"id":"nomad.job_promote","title":"nomad job promote <id>","summary":"Promote a canary deployment — replaces the rest of the allocations with the new version.","description":"Promote a canary deployment — replaces the rest of the allocations with the new version.","kind":"script","risk":"high","side_effects":["Old allocations are gradually replaced per the update stanza.","In-flight requests on replaced allocs may drop (subject to shutdown_delay)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID with an in-progress canary.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Promote canary","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_resources","title":"nomad job inspect <id> (resource summary)","summary":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","description":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","kind":"script","risk":"low","side_effects":["One read-only API call (job inspect).","Read-only — never writes or mutates job state."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Show current resources per group/task","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_restart","title":"nomad job restart <id>","summary":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","description":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","kind":"script","risk":"high","side_effects":["Every targeted task is stopped and started again, batch by batch.","In-flight requests on restarting allocs may drop (subject to shutdown_delay).","mode=migrate reschedules allocations, possibly onto different nodes."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"batch_size","type":"string","required":false,"default":"1","description":"Allocations per batch — a count (\"2\") or a percentage of running allocs (\"25%\").","validation":{"pattern":"^[1-9][0-9]{0,3}%?$"}},{"name":"mode","type":"string","required":false,"default":"in_place","description":"in_place restarts tasks in the existing allocations; migrate stops them and schedules replacements.","validation":{"enum":["in_place","migrate"]}},{"name":"group","type":"string","required":false,"default":"","description":"Restrict the restart to one task group (empty = all groups).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"task","type":"string","required":false,"default":"","description":"Restrict the restart to one task (empty = running tasks; only valid with mode=in_place).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rolling in-place restart, one alloc at a time","args":{"job":"api"}},{"title":"Migrate a quarter of the allocs per batch","args":{"batch_size":"25%","job":"api","mode":"migrate"}}],"search_terms":["rolling restart"]},{"id":"nomad.job_revert","title":"nomad job revert <id> <version>","summary":"Revert a job to a prior version. Equivalent to re-submitting that version.","description":"Revert a job to a prior version. Equivalent to re-submitting that version.","kind":"script","risk":"high","side_effects":["Job spec replaced with the prior version.","Triggers a rolling update (per the new/old spec's update stanza)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"version","type":"integer","required":true,"description":"Version number to revert to.","validation":{"min":0,"max":1000000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Roll back one version","args":{"job":"api","version":7}}],"search_terms":["rollback","roll back deployment","undo deploy","previous version"]},{"id":"nomad.job_scale","title":"nomad job scale <id> <group> <count>","summary":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","description":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","kind":"script","risk":"high","side_effects":["Scheduler creates or stops allocations to reach the target count.","Stopped allocations follow the kill_timeout / shutdown_delay stanzas."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"count","type":"integer","required":true,"description":"Target count.","validation":{"min":0,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Scale api group to 10","args":{"count":10,"group":"web","job":"api"}}],"search_terms":["scale up","scale down","more replicas"]},{"id":"nomad.job_start","title":"nomad job start <id>","summary":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","description":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","kind":"script","risk":"medium","side_effects":["A new job version is created and its allocations are scheduled.","Workload that was deliberately stopped starts running again."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID of a stopped (not purged) job.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Start a stopped job","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_status_all","title":"nomad job status (all)","summary":"List all jobs with their type, priority, status, and submit time.","description":"List all jobs with their type, priority, status, and submit time.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All jobs","args":{}},{"title":"All jobs in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_status_one","title":"nomad job status <id>","summary":"Show one job's full status — task groups, allocations, deployment.","description":"Show one job's full status — task groups, allocations, deployment.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One job","args":{"job":"api"}},{"title":"One job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["pods restarting","crash loop","tasks flapping"]},{"id":"nomad.job_stop","title":"nomad job stop <id>","summary":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","description":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","kind":"script","risk":"high","side_effects":["All allocations of the job receive a shutdown signal.","Job marked dead in catalog.","History retained unless --purge is used (this action does NOT purge)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Stop one job","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address (host:port).","description":"Show the current Raft leader address (host:port).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/status/leader"]}},{"id":"nomad.namespace_list","title":"nomad namespace list","summary":"List all namespaces in the cluster.","description":"List all namespaces in the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["namespace","list"]}},{"id":"nomad.node_drain","title":"nomad node drain -enable","summary":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","description":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","kind":"exec","risk":"high","side_effects":["Node stops accepting new allocations.","Existing allocations are migrated according to job spec (Migrate stanza).","May take minutes to complete depending on workload."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"deadline","type":"string","required":false,"default":"1h","description":"Force-eject after this duration if migration hasn't completed.","validation":{"pattern":"^[0-9]{1,4}[smh]$"}}],"examples":[{"title":"Drain one client","args":{"node_id":"abc12345"}}],"search_terms":["evacuate node","host maintenance"],"command":{"binary":"nomad","argv":["node","drain","-enable","-deadline","{{ args.deadline }}","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_drain_done","title":"nomad node drain -disable","summary":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","description":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","kind":"exec","risk":"medium","side_effects":["Drain mode disabled.","Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"End drain","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","drain","-disable","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_disable","title":"nomad node eligibility -disable","summary":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","description":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","kind":"exec","risk":"high","side_effects":["Node refuses new allocations.","Existing allocations stay running."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Cordon one","args":{"node_id":"abc12345"}}],"search_terms":["cordon","mark unschedulable"],"command":{"binary":"nomad","argv":["node","eligibility","-disable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_enable","title":"nomad node eligibility -enable","summary":"Re-enable a node for new allocations.","description":"Re-enable a node for new allocations.","kind":"exec","risk":"medium","side_effects":["Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Uncordon","args":{"node_id":"abc12345"}}],"search_terms":["uncordon"],"command":{"binary":"nomad","argv":["node","eligibility","-enable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_show","title":"Nodes with eligibility != eligible","summary":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","description":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Ineligible nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nomad node status -filter 'SchedulingEligibility != \"eligible\"'"]}},{"id":"nomad.node_pool_jobs","title":"nomad node pool jobs <pool>","summary":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","description":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Jobs in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_pool_list","title":"nomad node pool list","summary":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","description":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All node pools","args":{}}],"search_terms":[]},{"id":"nomad.node_pool_nodes","title":"nomad node pool nodes <pool>","summary":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","description":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Nodes in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_purge","title":"Purge a dead node (PUT /v1/node/<id>/purge)","summary":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","description":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","kind":"exec","risk":"critical","side_effects":["Node entry removed permanently (one API PUT).","Allocations on it are GC'd.","Only valid for nodes that are down — running nodes refuse purge."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Purge a dead node","args":{"node_id":"deadbeef"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","-X","PUT","/v1/node/{{ args.node_id }}/purge"]}},{"id":"nomad.node_status_all","title":"nomad node status","summary":"List all clients (nodes) with status, datacenter, drain state, eligibility.","description":"List all clients (nodes) with status, datacenter, drain state, eligibility.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster nodes","args":{}}],"search_terms":["node down","lost node"],"command":{"binary":"nomad","argv":["node","status","-verbose"]}},{"id":"nomad.node_status_one","title":"nomad node status <id>","summary":"Show one node's full detail — resources, allocations, events, drivers.","description":"Show one node's full detail — resources, allocations, events, drivers.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"One node","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","status","-verbose","{{ args.node_id }}"]}},{"id":"nomad.operator_autopilot_get_config","title":"nomad operator autopilot get-config","summary":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","description":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","autopilot","get-config"]}},{"id":"nomad.operator_autopilot_state","title":"GET /v1/operator/autopilot/health","summary":"Show the autopilot health view — leader health, follower lag, server stabilization.","description":"Show the autopilot health view — leader health, follower lag, server stabilization.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/operator/autopilot/health"]}},{"id":"nomad.operator_raft_list_peers","title":"nomad operator raft list-peers","summary":"List the Raft peers — voter status, suffrage, address.","description":"List the Raft peers — voter status, suffrage, address.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","list-peers"]}},{"id":"nomad.operator_raft_remove_peer","title":"nomad operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:4647"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","remove-peer","-peer-address","{{ args.address }}"]}},{"id":"nomad.operator_scheduler_get_config","title":"nomad operator scheduler get-config","summary":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","description":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster scheduler configuration","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","scheduler","get-config"]}},{"id":"nomad.plugin_status","title":"nomad plugin status [id]","summary":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","description":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"plugin_id","type":"string","required":false,"default":"","description":"Plugin ID or prefix (empty = list all plugins).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All CSI plugins","args":{}},{"title":"One plugin's health","args":{"plugin_id":"aws-ebs0"}}],"search_terms":["volume stuck","mount failing"]},{"id":"nomad.quota_list","title":"nomad quota list","summary":"List resource quotas (Enterprise feature).","description":"List resource quotas (Enterprise feature).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Quotas","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["quota","list"]}},{"id":"nomad.server_members","title":"nomad server members (json)","summary":"List the server members as JSON. Use for programmatic consumption.","description":"List the server members as JSON. Use for programmatic consumption.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members JSON","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/members"]}},{"id":"nomad.service_info","title":"nomad service info <name>","summary":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Registered service name (from nomad.service_list).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Instances of the \"redis\" service","args":{"service":"redis"}}],"search_terms":[]},{"id":"nomad.service_list","title":"nomad service list","summary":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","description":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All Nomad-registered services","args":{}},{"title":"Services in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.system_gc","title":"nomad system gc","summary":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","description":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","kind":"exec","risk":"medium","side_effects":["Old dead jobs/evals/allocs/deployments are removed from the catalog.","Frees Raft / state-store space."],"args":[],"examples":[{"title":"Trigger GC","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["system","gc"]}},{"id":"nomad.task_resources_set","title":"nomad job inspect | set task CPU/memory | job run","summary":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","description":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","kind":"script","risk":"high","side_effects":["Re-registers the job with the patched task resources (one read + one write API call).","Triggers a rolling update of the task group — allocations are replaced per its update stanza.","Setting memory below the task's real working set can cause OOM kills on the new allocations.","Refuses to write if the job changed since it was read (JobModifyIndex mismatch)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Task name. Empty selects the group's only task (errors if the group has more than one).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"cpu","type":"integer","required":false,"default":0,"description":"New CPU reservation in MHz. 0 leaves it unchanged.","validation":{"min":0,"max":1000000}},{"name":"memory","type":"integer","required":false,"default":0,"description":"New memory reservation (MemoryMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"memory_max","type":"integer","required":false,"default":0,"description":"New memory oversubscription cap (MemoryMaxMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Bump web/server to 1 vCPU + 1 GiB","args":{"cpu":1000,"group":"web","job":"api","memory":1024,"task":"server"}},{"title":"Raise memory only on a single-task group (auto-select)","args":{"group":"redis","job":"cache","memory":2048}}],"search_terms":["raise memory limit","bump cpu"]},{"id":"nomad.var_list","title":"nomad var list [prefix]","summary":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","description":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Values are never fetched — metadata only."],"args":[{"name":"prefix","type":"string","required":false,"default":"","description":"Path prefix to restrict the listing (empty = all variables).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_/.\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All variable paths","args":{}},{"title":"Variables under nomad/jobs","args":{"prefix":"nomad/jobs"}}],"search_terms":[]}]},{"version":"0.3.0","content_hash":"sha256:ff698f666f96d39e2df724b96b88943872b459eca9f83cf473c071140251e428","tarball_url":"https://registry.emisar.dev/v1/packs/nomad/0.3.0/ff698f666f96d39e2df724b96b88943872b459eca9f83cf473c071140251e428/pack.tar.gz","actions":[{"id":"nomad.acl_policies","title":"nomad acl policy list","summary":"List all ACL policy names.","description":"List all ACL policy names.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","policy","list"]}},{"id":"nomad.acl_token_self","title":"nomad acl token self","summary":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","description":"Show the runner's own token — name, type, policies, expiration. The Secret ID the CLI prints is redacted from the output.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only; the Secret ID field printed by the CLI is redacted before output."],"args":[],"examples":[{"title":"Self","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["acl","token","self"]}},{"id":"nomad.agent_force_leave","title":"nomad server force-leave <node>","summary":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","description":"Force a server out of the gossip pool. Use when a dead server can't leave on its own.","kind":"exec","risk":"high","side_effects":["The named server is marked left in serf.","Raft membership unaffected — use operator raft remove-peer for that."],"args":[{"name":"node_name","type":"string","required":true,"description":"Server node name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Force one server out","args":{"node_name":"nomad-server-3"}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","force-leave","{{ args.node_name }}"]}},{"id":"nomad.agent_info","title":"nomad agent-info","summary":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","description":"Show per-agent stats — runtime, raft, serf, vault, consul subsystems.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Agent info","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["agent-info"]}},{"id":"nomad.agent_members","title":"nomad server members","summary":"List the Serf gossip pool members.","description":"List the Serf gossip pool members.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["server","members","-detailed"]}},{"id":"nomad.agent_self","title":"GET /v1/agent/self","summary":"Show this agent's effective config (member name, region, datacenter, tags).","description":"Show this agent's effective config (member name, region, datacenter, tags).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Self config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/self"]}},{"id":"nomad.alloc_checks","title":"nomad alloc checks <id>","summary":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the Nomad-native service health-check results for one allocation — each check's name, group/task/service, status (success | failure | pending), and output. This is the Nomad-side health view with no Consul: is the alloc's service actually passing its checks, or failing one? Needs the allocation ID (get it from nomad.job_allocations or nomad.alloc_status). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Health checks for one alloc","args":{"alloc_id":"abc12345"}}],"search_terms":[]},{"id":"nomad.alloc_exec_redis_info","title":"Show Redis INFO inside an allocation (nomad alloc exec redis-cli info)","summary":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum.","description":"Show one section of Redis INFO from inside an allocation's task — runs the fixed command `redis-cli info <section>` via `nomad alloc exec`, with section bounded to the INFO enum. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.info when you can reach it directly. The command is fixed except the enum section — no freeform command, shell, host, port, or password is accepted, so it reads the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance. risk:medium, not low: `nomad alloc exec` runs inside the running container and INFO exposes memory/stats/ replication topology, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/ raw-driver tasks).","kind":"exec","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli info <section>` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"section","type":"string","required":false,"default":"default","description":"INFO section (bounded enum).","validation":{"enum":["default","all","server","clients","memory","persistence","stats","replication","cpu","commandstats","latencystats","cluster","keyspace","errorstats"]}}],"examples":[{"title":"Default INFO of Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}},{"title":"Replication topology","args":{"alloc_id":"abc12345","section":"replication","task":"redis"}}],"search_terms":[],"command":{"binary":"nomad","argv":["alloc","exec","-i=false","-t=false","-task","{{ args.task }}","{{ args.alloc_id }}","redis-cli","info","{{ args.section }}"]}},{"id":"nomad.alloc_exec_redis_ping","title":"Ping Redis inside an allocation (nomad alloc exec redis-cli ping)","summary":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG.","description":"Check whether the Redis inside one allocation's task is alive — runs the fixed command `redis-cli ping` via `nomad alloc exec` and returns PONG. This is for the incident where Redis is only reachable inside the alloc (no direct REDIS_URL from the runner); use the redis pack's redis.ping when you can reach it directly. The command is fixed — no freeform command, shell, host, port, or password is accepted, so it connects to the task's local redis-cli default (127.0.0.1:6379) and returns NOAUTH on a password-protected instance (itself a signal). risk:medium, not low: `nomad alloc exec` runs inside the running container and can expose internal state, so it is policy-gated even though the command only reads. Requires the alloc-exec namespace capability (alloc-node-exec for raw_exec/raw-driver tasks).","kind":"exec","risk":"medium","side_effects":["Executes the fixed read-only command `redis-cli ping` inside the task container.","Does not mutate Redis."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name inside the allocation that runs Redis.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Ping Redis in the cache task","args":{"alloc_id":"abc12345","task":"redis"}}],"search_terms":[],"command":{"binary":"nomad","argv":["alloc","exec","-i=false","-t=false","-task","{{ args.task }}","{{ args.alloc_id }}","redis-cli","ping"]}},{"id":"nomad.alloc_fs_ls","title":"List a directory in an allocation (nomad fs/ls API)","summary":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime.","description":"List a directory inside one allocation's filesystem — each entry's name, IsDir, size, file mode, and modtime. This is the \"what files did my task write to local/ or alloc/logs\" read for debugging, with no local CLI session. It calls Nomad's fs/ls API endpoint, which returns directory metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path defaults to the alloc root (/), is relative to it (Nomad contains it to the alloc dir), and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only (directory metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":false,"default":"/","description":"Directory to list, relative to the alloc root (e.g. local, alloc/logs, secrets). Defaults to the alloc root \"/\". No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}}],"examples":[{"title":"List the alloc root","args":{"alloc_id":"abc12345"}},{"title":"List the task's local/ directory","args":{"alloc_id":"abc12345","path":"local"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/client/fs/ls/{{ args.alloc_id }}?path={{ args.path }}"]}},{"id":"nomad.alloc_fs_stat","title":"Stat a path in an allocation (nomad fs/stat API)","summary":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type.","description":"Show the stat metadata of one path inside an allocation's filesystem — name, IsDir, size, file mode, modtime, and content type. This is the \"does this file exist / how big is it / when was it written\" read. It calls Nomad's fs/stat API endpoint, which returns metadata only and NEVER streams file contents, so it cannot leak a rendered-secret template the way `nomad alloc fs <file>` (cat) would. path is relative to the alloc root (Nomad contains it to the alloc dir) and rejects \"..\", absolute host paths, and shell metacharacters. Requires a Nomad token with the read-fs capability on the namespace.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only (file metadata only — no file contents)."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"Path to stat, relative to the alloc root (e.g. local/app.log, secrets/.env). No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^(/|\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*)$","max_length":256}}],"examples":[{"title":"Stat a task's log file","args":{"alloc_id":"abc12345","path":"alloc/logs/app.stdout.0"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/client/fs/stat/{{ args.alloc_id }}?path={{ args.path }}"]}},{"id":"nomad.alloc_fs_tail","title":"Tail a file inside an allocation (nomad alloc fs -tail)","summary":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say.","description":"Tail the last lines of one file inside an allocation's filesystem — the read for \"what did my task actually render into local/config.json\" when the task logs do not say. Unlike nomad.alloc_logs, which returns a task's stdout or stderr stream, this reads a FILE the task wrote. It is medium rather than low because a rendered template can hold whatever the job author put in it, so the content is not knowable from the action alone. Two bounds keep that honest — path rejects the secrets/ tree outright, and lines is capped — but neither can vouch for a file this action has never seen; treat the tier as the promise and the redaction as a backstop. Requires a Nomad token with read-fs on the namespace.","kind":"script","risk":"medium","side_effects":["One API call through the Nomad CLI.","Read-only; nothing in the allocation is modified.","Returns file CONTENT, unlike alloc_fs_ls and alloc_fs_stat which return metadata only. A file a job author rendered may contain anything they put in it.","The packaged script refuses the secrets/ tree before calling nomad, so Nomad's own rendered-credential mount cannot be read through this action."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations / nomad.alloc_status).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"path","type":"string","required":true,"description":"File to tail, relative to the alloc root (e.g. local/config.json, alloc/logs/app.stdout.0). The secrets/ tree is rejected — that is where Nomad mounts rendered credentials. No \"..\", absolute host paths, or shell metacharacters.","validation":{"pattern":"^\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*(/\\.?[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*)*$","max_length":256}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many trailing lines to return.","validation":{"min":1,"max":500}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region. Empty keeps the runner's ambient default.","validation":{"pattern":"^[a-zA-Z0-9_-]{0,128}$"}}],"examples":[{"title":"Tail a rendered config file","args":{"alloc_id":"abc12345","path":"local/config.json"}},{"title":"Last 20 lines of a task's log file","args":{"alloc_id":"abc12345","lines":20,"path":"alloc/logs/app.stdout.0"}}],"search_terms":[]},{"id":"nomad.alloc_list_by_meta","title":"List allocations by job meta (GET /v1/allocations?filter=Job.Meta[…])","summary":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","description":"List allocations cluster-wide whose JOB's `meta` stanza has a key equal to a value — e.g. every allocation of terraform-managed jobs (managed_by=terraform) in one call, instead of walking jobs one by one with nomad.job_allocations. The filter runs server-side against the job embedded in each allocation; alloc rows themselves carry no meta, so use nomad.job_list_by_meta to see the labels. Omit meta_key/meta_value to list every allocation. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all allocations).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All allocations (compact)","args":{}},{"title":"Allocations of terraform-managed jobs","args":{"meta_key":"managed_by","meta_value":"terraform"}}],"search_terms":[]},{"id":"nomad.alloc_logs","title":"Tail a task's application logs — stdout (nomad alloc logs)","summary":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout.","description":"Tail application logs (stdout) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stdout. This is the read for \"show me the app logs\" or \"tail the service output\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs_stderr for the stderr stream (errors, stack traces, panics).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stdout lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stdout lines while chasing a restart","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_logs_stderr","title":"Tail a task's application logs — stderr (nomad alloc logs -stderr)","summary":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output).","description":"Tail application error logs (stderr) from one task in a Nomad allocation — the last N lines the app/service/container wrote to stderr (errors, stack traces, panics, crash output). This is the read for \"show me the error logs\" or \"why did it crash\" during an incident or cutover preflight, instead of a local CLI session. Needs the allocation ID and task name: when you only have the job name, call nomad.job_allocations first to list its allocations and pick the running one. Use nomad.alloc_logs for the stdout stream.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix (from nomad.job_allocations when you only have the job name).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Last 200 stderr lines from the web task","args":{"alloc_id":"abc12345","task":"web"}},{"title":"Last 500 stderr lines after a crash","args":{"alloc_id":"abc12345","tail":500,"task":"redis"}}],"search_terms":[]},{"id":"nomad.alloc_restart","title":"nomad alloc restart <id> [task]","summary":"Restart one task (or all tasks if not specified) in one allocation.","description":"Restart one task (or all tasks if not specified) in one allocation.","kind":"exec","risk":"high","side_effects":["Task(s) receive SIGTERM then SIGKILL after kill_timeout.","In-flight requests drop unless shutdown_delay is set."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all tasks).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Restart one task","args":{"alloc_id":"abc12345","task":"web"}}],"search_terms":["restart pod","bounce task"],"command":{"binary":"/bin/sh","argv":["-c","if [ -n \"${1}\" ]; then nomad alloc restart -task \"$1\" \"$2\"; else nomad alloc restart \"$2\"; fi","emisar","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_signal","title":"nomad alloc signal -s <signal> <id> [task]","summary":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","description":"Send a UNIX signal to one task (or all tasks). Common uses: SIGHUP to reload config, SIGUSR1 for app-specific behavior.","kind":"exec","risk":"high","side_effects":["Targeted task(s) receive the signal.","Effect depends on the application's signal handling."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"signal","type":"string","required":true,"description":"Signal name (HUP, USR1, USR2, etc).","validation":{"enum":["HUP","USR1","USR2","INT","TERM","QUIT"]}},{"name":"task","type":"string","required":false,"default":"","description":"Specific task (empty = all).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"SIGHUP to reload","args":{"alloc_id":"abc12345","signal":"HUP","task":"web"}}],"search_terms":["send sighup","reload config"],"command":{"binary":"/bin/sh","argv":["-c","if [ -n \"${1}\" ]; then nomad alloc signal -s {{ args.signal }} -task \"$1\" \"$2\"; else nomad alloc signal -s {{ args.signal }} \"$2\"; fi","emisar","{{ args.task }}","{{ args.alloc_id }}"]}},{"id":"nomad.alloc_stats","title":"GET /v1/client/allocation/<id>/stats","summary":"Show CPU + memory + network stats for one allocation.","description":"Show CPU + memory + network stats for one allocation.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Stats","args":{"alloc_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/client/allocation/{{ args.alloc_id }}/stats"]}},{"id":"nomad.alloc_status","title":"nomad alloc status <id>","summary":"Show one allocation's full state — task states, restarts, last events.","description":"Show one allocation's full state — task states, restarts, last events.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One alloc","args":{"alloc_id":"abc12345"}},{"title":"One alloc in the \"prod\" namespace","args":{"alloc_id":"abc12345","namespace":"prod"}}],"search_terms":["crash loop","tasks flapping","oom killed","restart loop"]},{"id":"nomad.alloc_stop","title":"nomad alloc stop <id>","summary":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","description":"Stop one allocation. The scheduler reschedules it (per the job's reschedule stanza).","kind":"exec","risk":"high","side_effects":["Allocation is stopped + replaced.","Brief unavailability for the running container."],"args":[{"name":"alloc_id","type":"string","required":true,"description":"Allocation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Force-reschedule","args":{"alloc_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["alloc","stop","{{ args.alloc_id }}"]}},{"id":"nomad.csi_volume_list","title":"nomad volume status","summary":"List all registered CSI volumes with claim count + state.","description":"List all registered CSI volumes with claim count + state.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"CSI volumes","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["volume","status"]}},{"id":"nomad.csi_volume_status","title":"nomad volume status <id>","summary":"Show one CSI volume's full state — claims, allocations using it, plugin status.","description":"Show one CSI volume's full state — claims, allocations using it, plugin status.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"volume_id","type":"string","required":true,"description":"Volume ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"One volume","args":{"volume_id":"data-volume-1"}}],"search_terms":[],"command":{"binary":"nomad","argv":["volume","status","{{ args.volume_id }}"]}},{"id":"nomad.deployment_fail","title":"nomad deployment fail <id>","summary":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","description":"Manually fail an in-progress deployment — halts the rollout immediately and, if the job's update stanza has auto_revert, rolls back to the last stable version. The \"abort this bad rollout now\" verb. Get the deployment ID from nomad.deployment_list or nomad.job_deployments.","kind":"exec","risk":"high","side_effects":["The rollout stops; no further canaries or placements from this deployment.","With auto_revert, the job rolls back to its last stable version."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Abort a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":["abort rollout","cancel deployment"],"command":{"binary":"nomad","argv":["deployment","fail","-detach","{{ args.deployment_id }}"]}},{"id":"nomad.deployment_list","title":"nomad deployment list","summary":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","description":"List all deployments cluster-wide with their job, status, and description — the \"what is rolling out right now\" read. Use nomad.deployment_status for one deployment's full canary/health detail, or nomad.job_deployments for one job's history.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All deployments","args":{}},{"title":"Deployments in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":["deploy stuck","rollout stalled"]},{"id":"nomad.deployment_pause","title":"nomad deployment pause <id>","summary":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","description":"Pause an in-progress deployment — placements stop where they are while you investigate; already-placed allocations keep running. Resume with nomad.deployment_resume or abort with nomad.deployment_fail.","kind":"exec","risk":"medium","side_effects":["No further placements from this deployment until resumed."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Pause a rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["deployment","pause","{{ args.deployment_id }}"]}},{"id":"nomad.deployment_resume","title":"nomad deployment resume <id>","summary":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","description":"Resume a paused deployment — placements continue from where nomad.deployment_pause stopped them.","kind":"exec","risk":"medium","side_effects":["The rollout continues; new allocations are placed per the update stanza."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID or prefix (from nomad.deployment_list).","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Resume a paused rollout","args":{"deployment_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["deployment","resume","-detach","{{ args.deployment_id }}"]}},{"id":"nomad.deployment_status","title":"nomad deployment status <id>","summary":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","description":"Show one deployment's state — per-task-group desired/placed/healthy/unhealthy.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"deployment_id","type":"string","required":true,"description":"Deployment ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Deployment status","args":{"deployment_id":"abc12345"}}],"search_terms":["deploy stuck","rollout stalled","deploy failing"],"command":{"binary":"nomad","argv":["deployment","status","-verbose","{{ args.deployment_id }}"]}},{"id":"nomad.eval_list","title":"nomad eval list","summary":"List all recent evaluations across the cluster.","description":"List all recent evaluations across the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Recent evals","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["eval","list","-verbose"]}},{"id":"nomad.eval_status","title":"nomad eval status <id>","summary":"Show one evaluation's status — placement failures, queued allocations, blocked count.","description":"Show one evaluation's status — placement failures, queued allocations, blocked count.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"eval_id","type":"string","required":true,"description":"Evaluation ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Eval status","args":{"eval_id":"abc12345"}}],"search_terms":["stuck pending","not scheduling"],"command":{"binary":"nomad","argv":["eval","status","-verbose","{{ args.eval_id }}"]}},{"id":"nomad.event_snapshot","title":"Snapshot recent Nomad events (bounded /v1/event/stream)","summary":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session.","description":"Show a bounded snapshot of the Nomad event stream — recent Job, Allocation, Evaluation, Deployment, and Node events for incident triage, with no local CLI session. Nomad has no \"last N events\" query: /v1/event/stream is a forward feed whose only history is the broker's replay buffer (~100 events). This reads it from index=1 (replays the buffer, then live events) for `seconds` seconds, capped at 256 KiB, then returns — so it never hangs. Optionally filter to one `topic` or one `namespace`. Output is NDJSON: one {Index, Events:[...]} batch per line. Requires a token that can read the event stream.","kind":"script","risk":"low","side_effects":["Opens the Nomad event stream for a bounded time window.","Read-only."],"args":[{"name":"seconds","type":"integer","required":false,"default":5,"description":"How long to read the stream — the snapshot window, in seconds.","validation":{"min":1,"max":15}},{"name":"topic","type":"string","required":false,"default":"","description":"Filter to one event topic (empty = all topics). One of Job, Allocation, Evaluation, Deployment, Node, Service, or an ACL topic.","validation":{"pattern":"^(Job|Allocation|Evaluation|Deployment|Node|Service|ACLToken|ACLPolicy|ACLRole|ACLAuthMethod|ACLBindingRule|NodePool)?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Filter to one namespace (empty = the runner's ambient/default).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_-]{0,127})?$"}}],"examples":[{"title":"Recent events across all topics (5s window)","args":{}},{"title":"Recent allocation events only","args":{"topic":"Allocation"}},{"title":"Recent events in one namespace, 10s window","args":{"namespace":"production","seconds":10}}],"search_terms":[]},{"id":"nomad.host_volume_list","title":"Host volumes from /v1/nodes","summary":"List host-volume declarations across all client nodes.","description":"List host-volume declarations across all client nodes.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Host volumes","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/nodes"]}},{"id":"nomad.job_action_run","title":"nomad action -job <job> -group <group> -task <task> <name>","summary":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+).","description":"Run a job-spec-defined action inside a running allocation (Nomad 1.7+). Nomad job authors declare named commands in the task's `action` blocks; this executes ONE of them by name — whatever command the job spec declares, with the task's own environment and filesystem. The pack fixes nothing about the command itself, so treat this as remote execution bounded by the job author, not by this pack. List a job's declared actions via nomad.job_inspect (TaskGroups[].Tasks[].Actions). Requires a token with alloc-exec.","kind":"exec","risk":"high","side_effects":["The job-defined command runs inside the task's container/environment.","Effect depends entirely on what the job author declared."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":true,"description":"Task name.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"action_name","type":"string","required":true,"description":"The action name declared in the job spec's `action` block.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Run a job-declared action","args":{"action_name":"reload-config","group":"web","job":"api","task":"app"}}],"search_terms":[],"command":{"binary":"nomad","argv":["action","-job","{{ args.job }}","-group","{{ args.group }}","-task","{{ args.task }}","--","{{ args.action_name }}"]}},{"id":"nomad.job_allocations","title":"nomad job allocs <id>","summary":"List all allocations for one job.","description":"List all allocations for one job.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Allocations","args":{"job":"api"}},{"title":"Allocations in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_deployments","title":"nomad job deployments <id>","summary":"List deployment history for one job (rolling updates, canary, blue-green).","description":"List deployment history for one job (rolling updates, canary, blue-green).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Deployments","args":{"job":"api"}}],"search_terms":[],"command":{"binary":"nomad","argv":["job","deployments","-verbose","{{ args.job }}"]}},{"id":"nomad.job_dispatch","title":"nomad job dispatch <id>","summary":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","description":"Dispatch a parameterized job with optional meta variables; a new instance of the job's workload starts running on the cluster with the values you pass.","kind":"exec","risk":"high","side_effects":["A new dispatched job instance is created and scheduled.","Counts toward job history."],"args":[{"name":"job","type":"string","required":true,"description":"Parameterized job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"meta_kv","type":"string","required":false,"default":"","description":"Optional meta as 'k=v,k2=v2' (no spaces around =).","validation":{"pattern":"^([a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256}(,[a-zA-Z0-9_]{1,64}=[a-zA-Z0-9_./\\-]{0,256})*)?$","max_length":1024}}],"examples":[{"title":"Dispatch with meta","args":{"job":"batch-processor","meta_kv":"input=/tmp/data,priority=high"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","M=''; if [ -n ''\"$1\"'' ]; then for kv in $(echo ''\"$1\"'' | tr ',' ' '); do M=\"$M -meta $kv\"; done; fi; nomad job dispatch $M \"$2\"","emisar","{{ args.meta_kv }}","{{ args.job }}"]}},{"id":"nomad.job_eval","title":"nomad job eval <id>","summary":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","description":"Force a new evaluation for one job — kick the scheduler to retry placement now. With force_reschedule=true, failed allocations are rescheduled even if they are not currently eligible (past their reschedule backoff) — the \"we fixed the cause, try again\" verb after an incident.","kind":"exec","risk":"medium","side_effects":["A new evaluation is created; the scheduler may place or reschedule allocations."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"force_reschedule","type":"string","required":false,"default":"false","description":"true also reschedules failed allocations that are past their reschedule limit.","validation":{"enum":["false","true"]}}],"examples":[{"title":"Re-evaluate a job","args":{"job":"api"}},{"title":"Force failed allocs to reschedule","args":{"force_reschedule":"true","job":"api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.force_reschedule }}' = 'true' ]; then exec nomad job eval -detach -force-reschedule -- ''\"$1\"''; else exec nomad job eval -detach -- ''\"$1\"''; fi","emisar","{{ args.job }}"]}},{"id":"nomad.job_evaluations","title":"nomad job eval <id> (force re-evaluation)","summary":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","description":"Force a fresh evaluation of one job — the scheduler re-checks placement and constraints and may reschedule allocations. NOT read-only: the CLI `nomad job eval` creates a new evaluation, it does not just list them.","kind":"exec","risk":"medium","side_effects":["Creates a new evaluation for the job.","The scheduler reconciles the job; allocations may be moved or restarted."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Force a re-evaluation","args":{"job":"api"}}],"search_terms":[],"command":{"binary":"nomad","argv":["job","eval","-verbose","{{ args.job }}"]}},{"id":"nomad.job_health_snapshot","title":"Nomad job health snapshot","summary":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","description":"Return one bounded JSON snapshot of a job's desired and current allocation counts, configured task images, recent deployments, recent allocations, restart and failed-task events, and Nomad-native checks. Job environment, templates, variables, payloads, and other driver configuration are omitted.","kind":"script","risk":"low","side_effects":["Four fixed read-only Nomad API calls plus one checks read per returned allocation.","Allocation and event counts are bounded by validated arguments.","Read-only - never changes a job, deployment, allocation, or check."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty keeps the runner's ambient namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty keeps the runner's ambient region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}},{"name":"allocation_limit","type":"integer","required":false,"default":10,"description":"Maximum recent allocations and associated check reads.","validation":{"min":1,"max":25}},{"name":"events_per_task","type":"integer","required":false,"default":5,"description":"Maximum recent restart and failed events retained per task.","validation":{"min":1,"max":20}}],"examples":[{"title":"Recent health for an API job","args":{"job":"api"}},{"title":"Smaller production snapshot","args":{"allocation_limit":5,"events_per_task":3,"job":"api","namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_history","title":"nomad job history <id>","summary":"List all versions of one job with submitter + timestamp.","description":"List all versions of one job with submitter + timestamp.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"History","args":{"job":"api"}}],"search_terms":[],"command":{"binary":"nomad","argv":["job","history","-p","{{ args.job }}"]}},{"id":"nomad.job_inspect","title":"nomad job inspect <id>","summary":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Dump one job's full spec as JSON. This surfaces the job's `env` and `template` blocks, which routinely carry injected secrets (DB URLs, API keys, rendered Vault templates). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"script","risk":"high","side_effects":["One API call.","Read-only, but exposes the job's env/template blocks (may include secrets)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Inspect job","args":{"job":"api"}},{"title":"Inspect a job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["jobspec","job definition"]},{"id":"nomad.job_list_by_meta","title":"List jobs with meta (GET /v1/jobs?meta=true [&filter])","summary":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","description":"List jobs together with their `meta` stanza (managed_by, application, part_of, image_tag, …), optionally filtered server-side to the jobs whose meta key equals a value — e.g. every job with managed_by=terraform. This is the label-aware job discovery read: nomad.job_status_all shows no meta at all, and without this the only way to see a job's meta is nomad.job_inspect, one job at a time. Omit meta_key/meta_value to list every job with its meta. Requires jq on the runner host.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"meta_key","type":"string","required":false,"default":"","description":"Job meta key to filter on (empty = no filter, list all jobs).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-]{0,63})?$"}},{"name":"meta_value","type":"string","required":false,"default":"","description":"Exact value meta_key must equal (required when meta_key is set).","validation":{"pattern":"^([a-zA-Z0-9_][a-zA-Z0-9_.\\-/:]{0,255})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}}],"examples":[{"title":"All jobs with their meta","args":{}},{"title":"Jobs managed by Terraform","args":{"meta_key":"managed_by","meta_value":"terraform"}},{"title":"One application's jobs across all namespaces","args":{"meta_key":"application","meta_value":"blitz-website","namespace":"*"}}],"search_terms":[]},{"id":"nomad.job_periodic_force","title":"nomad job periodic force <id>","summary":"Force-run one periodic job NOW, ignoring schedule.","description":"Force-run one periodic job NOW, ignoring schedule.","kind":"exec","risk":"medium","side_effects":["A new periodic child job is created and dispatched.","Counts toward normal job history."],"args":[{"name":"job","type":"string","required":true,"description":"Periodic job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Force-run","args":{"job":"nightly-backup"}}],"search_terms":["run cron now","trigger scheduled job"],"command":{"binary":"nomad","argv":["job","periodic","force","{{ args.job }}"]}},{"id":"nomad.job_promote","title":"nomad job promote <id>","summary":"Promote a canary deployment — replaces the rest of the allocations with the new version.","description":"Promote a canary deployment — replaces the rest of the allocations with the new version.","kind":"exec","risk":"high","side_effects":["Old allocations are gradually replaced per the update stanza.","In-flight requests on replaced allocs may drop (subject to shutdown_delay)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID with an in-progress canary.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Promote canary","args":{"job":"api"}}],"search_terms":[],"command":{"binary":"nomad","argv":["job","promote","{{ args.job }}"]}},{"id":"nomad.job_resources","title":"nomad job inspect <id> (resource summary)","summary":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","description":"List the CPU and memory reservation and the replica count for every task group and task in a job — the compact read companion to nomad.task_resources_set, so you can see current limits before vertical-scaling. Projects only the resource fields from the full jobspec: per task the CPU (MHz), cores, MemoryMB, and MemoryMaxMB, and per group the count.","kind":"script","risk":"low","side_effects":["One read-only API call (job inspect).","Read-only — never writes or mutates job state."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Show current resources per group/task","args":{"job":"api"}}],"search_terms":[]},{"id":"nomad.job_restart","title":"nomad job restart <id>","summary":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","description":"Restart one job's allocations in controlled batches, waiting for each batch to come back up before the next — the safe whole-job restart that replaces N hand-rolled per-alloc restarts. mode=in_place restarts tasks inside the existing allocations; mode=migrate stops each batch and lets the scheduler place replacements (possibly on other nodes). Runs non-interactively (-yes -on-error=fail: aborts on the first failed batch).","kind":"script","risk":"high","side_effects":["Every targeted task is stopped and started again, batch by batch.","In-flight requests on restarting allocs may drop (subject to shutdown_delay).","mode=migrate reschedules allocations, possibly onto different nodes."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"batch_size","type":"string","required":false,"default":"1","description":"Allocations per batch — a count (\"2\") or a percentage of running allocs (\"25%\").","validation":{"pattern":"^[1-9][0-9]{0,3}%?$"}},{"name":"mode","type":"string","required":false,"default":"in_place","description":"in_place restarts tasks in the existing allocations; migrate stops them and schedules replacements.","validation":{"enum":["in_place","migrate"]}},{"name":"group","type":"string","required":false,"default":"","description":"Restrict the restart to one task group (empty = all groups).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"task","type":"string","required":false,"default":"","description":"Restrict the restart to one task (empty = running tasks; only valid with mode=in_place).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}}],"examples":[{"title":"Rolling in-place restart, one alloc at a time","args":{"job":"api"}},{"title":"Migrate a quarter of the allocs per batch","args":{"batch_size":"25%","job":"api","mode":"migrate"}}],"search_terms":["rolling restart"]},{"id":"nomad.job_revert","title":"nomad job revert <id> <version>","summary":"Revert a job to a prior version. Equivalent to re-submitting that version.","description":"Revert a job to a prior version. Equivalent to re-submitting that version.","kind":"exec","risk":"high","side_effects":["Job spec replaced with the prior version.","Triggers a rolling update (per the new/old spec's update stanza)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"version","type":"integer","required":true,"description":"Version number to revert to.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Roll back one version","args":{"job":"api","version":7}}],"search_terms":["rollback","roll back deployment","undo deploy","previous version"],"command":{"binary":"nomad","argv":["job","revert","{{ args.job }}","{{ args.version }}"]}},{"id":"nomad.job_scale","title":"nomad job scale <id> <group> <count>","summary":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","description":"Adjust the count for one task group; 0 stops every allocation and takes the group's service down.","kind":"exec","risk":"high","side_effects":["Scheduler creates or stops allocations to reach the target count.","Stopped allocations follow the kill_timeout / shutdown_delay stanzas."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"count","type":"integer","required":true,"description":"Target count.","validation":{"min":0,"max":10000}}],"examples":[{"title":"Scale api group to 10","args":{"count":10,"group":"web","job":"api"}}],"search_terms":["scale up","scale down","more replicas"],"command":{"binary":"nomad","argv":["job","scale","{{ args.job }}","{{ args.group }}","{{ args.count }}"]}},{"id":"nomad.job_start","title":"nomad job start <id>","summary":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","description":"Start a stopped job — schedules a new version based on its most recent one. The inverse of nomad.job_stop: the job must still be registered (stopped, not purged). Requires Nomad 1.9+ on the server and CLI.","kind":"exec","risk":"medium","side_effects":["A new job version is created and its allocations are scheduled.","Workload that was deliberately stopped starts running again."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID of a stopped (not purged) job.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Start a stopped job","args":{"job":"api"}}],"search_terms":[],"command":{"binary":"nomad","argv":["job","start","-detach","{{ args.job }}"]}},{"id":"nomad.job_status_all","title":"nomad job status (all)","summary":"List all jobs with their type, priority, status, and submit time.","description":"List all jobs with their type, priority, status, and submit time.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All jobs","args":{}},{"title":"All jobs in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.job_status_one","title":"nomad job status <id>","summary":"Show one job's full status — task groups, allocations, deployment.","description":"Show one job's full status — task groups, allocations, deployment.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"One job","args":{"job":"api"}},{"title":"One job in the \"prod\" namespace","args":{"job":"api","namespace":"prod"}}],"search_terms":["pods restarting","crash loop","tasks flapping"]},{"id":"nomad.job_stop","title":"nomad job stop <id>","summary":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","description":"Stop one job. All its allocations are stopped + GC'd. Use -purge to also remove from history.","kind":"exec","risk":"high","side_effects":["All allocations of the job receive a shutdown signal.","Job marked dead in catalog.","History retained unless --purge is used (this action does NOT purge)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}}],"examples":[{"title":"Stop one job","args":{"job":"api"}}],"search_terms":[],"command":{"binary":"nomad","argv":["job","stop","{{ args.job }}"]}},{"id":"nomad.leader","title":"GET /v1/status/leader","summary":"Show the current Raft leader address (host:port).","description":"Show the current Raft leader address (host:port).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Leader","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/status/leader"]}},{"id":"nomad.namespace_list","title":"nomad namespace list","summary":"List all namespaces in the cluster.","description":"List all namespaces in the cluster.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Namespaces","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["namespace","list"]}},{"id":"nomad.node_drain","title":"nomad node drain -enable","summary":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","description":"Enable drain mode on one node. Allocations migrate; new ones are blocked.","kind":"exec","risk":"high","side_effects":["Node stops accepting new allocations.","Existing allocations are migrated according to job spec (Migrate stanza).","May take minutes to complete depending on workload."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}},{"name":"deadline","type":"string","required":false,"default":"1h","description":"Force-eject after this duration if migration hasn't completed.","validation":{"pattern":"^[0-9]{1,4}[smh]$"}}],"examples":[{"title":"Drain one client","args":{"node_id":"abc12345"}}],"search_terms":["evacuate node","host maintenance"],"command":{"binary":"nomad","argv":["node","drain","-enable","-deadline","{{ args.deadline }}","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_drain_done","title":"nomad node drain -disable","summary":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","description":"Disable drain on one node. The node becomes eligible again (assuming eligibility wasn't separately disabled).","kind":"exec","risk":"medium","side_effects":["Drain mode disabled.","Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"End drain","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","drain","-disable","-yes","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_disable","title":"nomad node eligibility -disable","summary":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","description":"Mark one node ineligible for new allocations. Existing allocations are not migrated.","kind":"exec","risk":"high","side_effects":["Node refuses new allocations.","Existing allocations stay running."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Cordon one","args":{"node_id":"abc12345"}}],"search_terms":["cordon","mark unschedulable"],"command":{"binary":"nomad","argv":["node","eligibility","-disable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_enable","title":"nomad node eligibility -enable","summary":"Re-enable a node for new allocations.","description":"Re-enable a node for new allocations.","kind":"exec","risk":"medium","side_effects":["Node may immediately receive new allocations."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Uncordon","args":{"node_id":"abc12345"}}],"search_terms":["uncordon"],"command":{"binary":"nomad","argv":["node","eligibility","-enable","{{ args.node_id }}"]}},{"id":"nomad.node_eligibility_show","title":"Nodes with eligibility != eligible","summary":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","description":"List the client nodes that are ineligible for new allocations — drained or manually disabled — as a table with node ID, name, drain state, and status. A healthy cluster prints \"No nodes registered\". Read-only.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Ineligible nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","nomad node status -filter 'SchedulingEligibility != \"eligible\"'"]}},{"id":"nomad.node_pool_jobs","title":"nomad node pool jobs <pool>","summary":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","description":"List the jobs scheduled into one node pool — which workloads land on that segment of the fleet (Nomad 1.6+).","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Jobs in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_pool_list","title":"nomad node pool list","summary":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","description":"List all node pools with their descriptions — the fleet-segmentation view (Nomad 1.6+; the built-in pools are \"default\" and \"all\"). Use nomad.node_pool_nodes / nomad.node_pool_jobs to see what is inside one pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All node pools","args":{}}],"search_terms":[]},{"id":"nomad.node_pool_nodes","title":"nomad node pool nodes <pool>","summary":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","description":"List the client nodes in one node pool — ID, datacenter, status, drain and eligibility (Nomad 1.6+). Use \"all\" to see every node regardless of pool.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"pool","type":"string","required":true,"description":"Node pool name (from nomad.node_pool_list; \"default\" and \"all\" are built in).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Nodes in the default pool","args":{"pool":"default"}}],"search_terms":[]},{"id":"nomad.node_purge","title":"Purge a dead node (PUT /v1/node/<id>/purge)","summary":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","description":"Remove a dead (down) node from the catalog; allocations on it are GC'd. There is no `nomad node purge` CLI subcommand — this is the HTTP API (PUT /v1/node/<id>/purge). Only valid for nodes that are down.","kind":"exec","risk":"critical","side_effects":["Node entry removed permanently (one API PUT).","Allocations on it are GC'd.","Only valid for nodes that are down — running nodes refuse purge."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"Purge a dead node","args":{"node_id":"deadbeef"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","-X","PUT","/v1/node/{{ args.node_id }}/purge"]}},{"id":"nomad.node_status_all","title":"nomad node status","summary":"List all clients (nodes) with status, datacenter, drain state, eligibility.","description":"List all clients (nodes) with status, datacenter, drain state, eligibility.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster nodes","args":{}}],"search_terms":["node down","lost node"],"command":{"binary":"nomad","argv":["node","status","-verbose"]}},{"id":"nomad.node_status_one","title":"nomad node status <id>","summary":"Show one node's full detail — resources, allocations, events, drivers.","description":"Show one node's full detail — resources, allocations, events, drivers.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"node_id","type":"string","required":true,"description":"Node ID or prefix.","validation":{"pattern":"^[a-fA-F0-9][a-fA-F0-9\\-]{3,35}$"}}],"examples":[{"title":"One node","args":{"node_id":"abc12345"}}],"search_terms":[],"command":{"binary":"nomad","argv":["node","status","-verbose","{{ args.node_id }}"]}},{"id":"nomad.operator_autopilot_get_config","title":"nomad operator autopilot get-config","summary":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","description":"Show the autopilot configuration (dead-server cleanup, redundancy zones, server stabilization).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot config","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","autopilot","get-config"]}},{"id":"nomad.operator_autopilot_state","title":"GET /v1/operator/autopilot/health","summary":"Show the autopilot health view — leader health, follower lag, server stabilization.","description":"Show the autopilot health view — leader health, follower lag, server stabilization.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Autopilot state","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/operator/autopilot/health"]}},{"id":"nomad.operator_raft_list_peers","title":"nomad operator raft list-peers","summary":"List the Raft peers — voter status, suffrage, address.","description":"List the Raft peers — voter status, suffrage, address.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Raft peers","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","list-peers"]}},{"id":"nomad.operator_raft_remove_peer","title":"nomad operator raft remove-peer","summary":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","description":"Forcibly removes a server from Raft. Use ONLY when a server is permanently gone and autopilot hasn't cleaned it up.","kind":"exec","risk":"critical","side_effects":["Raft membership changes immediately.","Quorum size adjusts.","Wrong target = lost quorum / split brain."],"args":[{"name":"address","type":"string","required":true,"description":"Raft address (host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127}:[0-9]{1,5}$"}}],"examples":[{"title":"Remove dead server","args":{"address":"10.0.0.5:4647"}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","raft","remove-peer","-peer-address","{{ args.address }}"]}},{"id":"nomad.operator_scheduler_get_config","title":"nomad operator scheduler get-config","summary":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","description":"Show the cluster's scheduler configuration — the scheduler algorithm (binpack/spread), memory oversubscription, preemption settings (system/batch/ service/sysbatch), job-registration rejection, and eval-broker pause state. This is the \"why is placement behaving this way / is preemption on\" read for incident triage. Read-only; requires a Nomad token with the operator:read capability.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Cluster scheduler configuration","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","scheduler","get-config"]}},{"id":"nomad.plugin_status","title":"nomad plugin status [id]","summary":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","description":"Show CSI plugin health — controller/node instance counts and whether the plugin is healthy. When a CSI volume is stuck, the answer is usually here, not in the volume itself. Omit plugin_id to list every plugin; pass one for its detail (from the list, or nomad.csi_volume_status's \"Plugin ID\").","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"plugin_id","type":"string","required":false,"default":"","description":"Plugin ID or prefix (empty = list all plugins).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_.\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All CSI plugins","args":{}},{"title":"One plugin's health","args":{"plugin_id":"aws-ebs0"}}],"search_terms":["volume stuck","mount failing"]},{"id":"nomad.quota_list","title":"nomad quota list","summary":"List resource quotas (Enterprise feature).","description":"List resource quotas (Enterprise feature).","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Quotas","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["quota","list"]}},{"id":"nomad.server_members","title":"nomad server members (json)","summary":"List the server members as JSON. Use for programmatic consumption.","description":"List the server members as JSON. Use for programmatic consumption.","kind":"exec","risk":"low","side_effects":["One API call.","Read-only."],"args":[],"examples":[{"title":"Members JSON","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["operator","api","/v1/agent/members"]}},{"id":"nomad.service_info","title":"nomad service info <name>","summary":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","description":"Show the live instances of one service in Nomad's native service discovery (no Consul) — each instance's address, port, node, and allocation ID. This is the \"where is this service running, on what address\" read for a registered service name (list them with nomad.service_list). Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"service","type":"string","required":true,"description":"Registered service name (from nomad.service_list).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"Instances of the \"redis\" service","args":{"service":"redis"}}],"search_terms":[]},{"id":"nomad.service_list","title":"nomad service list","summary":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","description":"List the services registered in Nomad's native service discovery (no Consul) — the registered service names and their tags in the current namespace. This is the \"what services does Nomad know about\" read; use nomad.service_info to see the live instances (address, port, node, alloc) behind one service. Requires a Nomad token with the read-job capability on the namespace.","kind":"script","risk":"low","side_effects":["One API call.","Read-only."],"args":[{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) keeps the runner's ambient NOMAD_NAMESPACE or the default namespace.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All Nomad-registered services","args":{}},{"title":"Services in the \"prod\" namespace","args":{"namespace":"prod"}}],"search_terms":[]},{"id":"nomad.system_gc","title":"nomad system gc","summary":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","description":"Force a system-wide GC of jobs, allocations, evaluations, and deployments past their GC threshold.","kind":"exec","risk":"medium","side_effects":["Old dead jobs/evals/allocs/deployments are removed from the catalog.","Frees Raft / state-store space."],"args":[],"examples":[{"title":"Trigger GC","args":{}}],"search_terms":[],"command":{"binary":"nomad","argv":["system","gc"]}},{"id":"nomad.task_resources_set","title":"nomad job inspect | set task CPU/memory | job run","summary":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","description":"Vertical-scale one task: set its CPU and/or memory limits and re-register the job. Nomad has no atomic resource-change command, so this fetches the live jobspec, patches only the named task's CPU (MHz), MemoryMB, and MemoryMaxMB, and re-registers it with an optimistic JobModifyIndex check. The cloud never supplies jobspec JSON — only the bounded ids and integers below. Pair with nomad.job_resources to read current limits first, and nomad.job_scale to change the replica count.","kind":"script","risk":"high","side_effects":["Re-registers the job with the patched task resources (one read + one write API call).","Triggers a rolling update of the task group — allocations are replaced per its update stanza.","Setting memory below the task's real working set can cause OOM kills on the new allocations.","Refuses to write if the job changed since it was read (JobModifyIndex mismatch)."],"args":[{"name":"job","type":"string","required":true,"description":"Job ID.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"group","type":"string","required":true,"description":"Task group.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}$"}},{"name":"task","type":"string","required":false,"default":"","description":"Task name. Empty selects the group's only task (errors if the group has more than one).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127})?$"}},{"name":"cpu","type":"integer","required":false,"default":0,"description":"New CPU reservation in MHz. 0 leaves it unchanged.","validation":{"min":0,"max":1000000}},{"name":"memory","type":"integer","required":false,"default":0,"description":"New memory reservation (MemoryMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}},{"name":"memory_max","type":"integer","required":false,"default":0,"description":"New memory oversubscription cap (MemoryMaxMB). 0 leaves it unchanged.","validation":{"min":0,"max":4194304}}],"examples":[{"title":"Bump web/server to 1 vCPU + 1 GiB","args":{"cpu":1000,"group":"web","job":"api","memory":1024,"task":"server"}},{"title":"Raise memory only on a single-task group (auto-select)","args":{"group":"redis","job":"cache","memory":2048}}],"search_terms":["raise memory limit","bump cpu"]},{"id":"nomad.var_list","title":"nomad var list [prefix]","summary":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","description":"List Nomad variable METADATA — path, namespace, and modify time only, never the values. Answers \"does the variable exist and when did it change\" during a debugging session without touching secret material (there is deliberately no variable-read action in this pack). Optionally restrict to a path prefix.","kind":"script","risk":"low","side_effects":["One API call.","Read-only.","Values are never fetched — metadata only."],"args":[{"name":"prefix","type":"string","required":false,"default":"","description":"Path prefix to restrict the listing (empty = all variables).","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_/.\\-]{0,127})?$"}},{"name":"namespace","type":"string","required":false,"default":"","description":"Nomad namespace to target. Empty (default) = the default namespace; \"*\" = all namespaces.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,127}|\\*)?$"}},{"name":"region","type":"string","required":false,"default":"","description":"Nomad region to target. Empty (default) keeps the runner's ambient NOMAD_REGION or the agent's region.","validation":{"pattern":"^([a-zA-Z0-9][a-zA-Z0-9_\\-]{0,63})?$"}}],"examples":[{"title":"All variable paths","args":{}},{"title":"Variables under nomad/jobs","args":{"prefix":"nomad/jobs"}}],"search_terms":[]}]}],"retired_below":"0.2.8"},{"id":"oidc-jwks","name":"OIDC and JWKS diagnostics","version":"0.1.6","description":"Generic read-only OpenID Connect discovery and JWKS diagnostics, plus local key-ID comparison and protected JWT-header inspection. Network actions use explicit HTTPS URLs, never follow redirects, and never submit bearer tokens.","vendor":"emisar","homepage":"https://emisar.dev/packs/oidc-jwks","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/oidc-jwks","content_hash":"sha256:dca15cd1e7a4bcf613d05f4cfb9d677f5088d76b0915fead5028a9065f4196bf","tarball_url":"https://registry.emisar.dev/v1/packs/oidc-jwks/0.1.6/dca15cd1e7a4bcf613d05f4cfb9d677f5088d76b0915fead5028a9065f4196bf/pack.tar.gz","requires":{"os":["linux"],"binaries":["bash","curl","jq","base64"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Discovery and JWKS documents are public metadata. The runner needs outbound HTTPS access to the exact issuer or JWKS host supplied to an action.","env":[{"name":"OIDC_CA_CERT","description":"Optional PEM CA bundle for a private issuer.","example":"/etc/emisar/oidc-ca.pem"}],"notes":["`OIDC_CA_CERT` must be allowlisted in `execution.inherit_env` when set.","Explicit HTTPS URLs can still name private or loopback services; restrict destinations with runner policy and network egress controls when agents must not reach them.","Network actions do not follow redirects or automatically fetch a secondary URL. Validate discovery first, then call oidc.jwks with the returned jwks_uri explicitly.","oidc.jwt_header decodes metadata only. It does not verify the signature, issuer, audience, expiry, or any other claim."],"verify":"oidc.validate_discovery"},"actions":[{"id":"oidc.compare_key_ids","title":"Compare authoritative and consumer key IDs","summary":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","description":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","kind":"script","risk":"low","side_effects":["Local JSON parsing only.","Does not perform network or filesystem I/O."],"args":[{"name":"authoritative_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs from the authoritative JWKS.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}},{"name":"consumer_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs observed by the consumer.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}}],"examples":[{"title":"Detect a stale consumer","args":{"authoritative_key_ids_json":"[\"current\",\"next\"]","consumer_key_ids_json":"[\"current\",\"old\"]"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"authoritative_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_covers_authoritative":{"type":"boolean"},"exact_match":{"type":"boolean"},"extra_count":{"maximum":128,"minimum":0,"type":"integer"},"extra_in_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"missing_count":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"relation":{"enum":["equal","consumer_missing","consumer_extra","consumer_missing_and_extra"]},"shared_count":{"maximum":128,"minimum":0,"type":"integer"},"truncated":{"additionalProperties":false,"properties":{"extra_in_consumer":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"maximum":128,"minimum":0,"type":"integer"}},"required":["missing_from_consumer","extra_in_consumer"],"type":"object"}},"required":["authoritative_count","consumer_count","shared_count","missing_count","extra_count","missing_from_consumer","extra_in_consumer","truncated","exact_match","consumer_covers_authoritative","relation"],"type":"object"}},{"id":"oidc.discovery","title":"Fetch OIDC discovery metadata","summary":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","description":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect an issuer","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[]},{"id":"oidc.jwks","title":"Fetch a public JWKS","summary":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","description":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the exact JWKS URL.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"jwks_uri","type":"string","required":true,"description":"Exact HTTPS JWKS URL without credentials, a query, or a fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect issuer signing keys","args":{"jwks_uri":"https://accounts.example.com/keys"}}],"search_terms":[]},{"id":"oidc.jwt_header","title":"Decode a protected JWT header","summary":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","description":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","kind":"script","risk":"low","side_effects":["Local base64url and JSON decoding only.","The sensitive compact token is passed through environment, not argv, and is never emitted."],"args":[{"name":"jwt","type":"string","required":true,"sensitive":true,"description":"Compact JWS or JWE serialization.","validation":{"pattern":"^(?:[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*|[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$","max_length":16384}}],"examples":[{"title":"Inspect protected signing metadata","args":{"jwt":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImN1cnJlbnQifQ.e30.signature"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"alg":{"maxLength":64,"minLength":1,"type":"string"},"crit":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":["array","null"]},"cty":{"maxLength":128,"type":["string","null"]},"enc":{"maxLength":64,"type":["string","null"]},"jku":{"maxLength":512,"type":["string","null"]},"kid":{"maxLength":256,"type":["string","null"]},"present_fields":{"items":{"maxLength":8,"type":"string"},"maxItems":11,"type":"array"},"segment_count":{"enum":[3,5]},"serialization":{"enum":["jws","jwe"]},"typ":{"maxLength":64,"type":["string","null"]},"x5t":{"maxLength":64,"type":["string","null"]},"x5t_s256":{"maxLength":64,"type":["string","null"]},"x5u":{"maxLength":512,"type":["string","null"]},"zip":{"maxLength":32,"type":["string","null"]}},"required":["serialization","segment_count","alg","enc","kid","typ","cty","zip","crit","jku","x5u","x5t","x5t_s256","present_fields"],"type":"object"}},{"id":"oidc.validate_discovery","title":"Validate OIDC discovery metadata","summary":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","description":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Validate issuer metadata","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"discovery_url":{"type":"string"},"issuer":{"type":"string"},"jwks_uri":{"type":"string"},"valid":{"const":true}},"required":["valid","issuer","discovery_url","jwks_uri"],"type":"object"}}],"previous_versions":[{"version":"0.1.5","content_hash":"sha256:8210d84b3e73444790d871ab0f0bedd137f077afa0b389cb9c492461088d8043","tarball_url":"https://registry.emisar.dev/v1/packs/oidc-jwks/0.1.5/8210d84b3e73444790d871ab0f0bedd137f077afa0b389cb9c492461088d8043/pack.tar.gz","actions":[{"id":"oidc.compare_key_ids","title":"Compare authoritative and consumer key IDs","summary":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","description":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","kind":"script","risk":"low","side_effects":["Local JSON parsing only.","Does not perform network or filesystem I/O."],"args":[{"name":"authoritative_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs from the authoritative JWKS.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}},{"name":"consumer_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs observed by the consumer.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}}],"examples":[{"title":"Detect a stale consumer","args":{"authoritative_key_ids_json":"[\"current\",\"next\"]","consumer_key_ids_json":"[\"current\",\"old\"]"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"authoritative_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_covers_authoritative":{"type":"boolean"},"exact_match":{"type":"boolean"},"extra_count":{"maximum":128,"minimum":0,"type":"integer"},"extra_in_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"missing_count":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"relation":{"enum":["equal","consumer_missing","consumer_extra","consumer_missing_and_extra"]},"shared_count":{"maximum":128,"minimum":0,"type":"integer"},"truncated":{"additionalProperties":false,"properties":{"extra_in_consumer":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"maximum":128,"minimum":0,"type":"integer"}},"required":["missing_from_consumer","extra_in_consumer"],"type":"object"}},"required":["authoritative_count","consumer_count","shared_count","missing_count","extra_count","missing_from_consumer","extra_in_consumer","truncated","exact_match","consumer_covers_authoritative","relation"],"type":"object"}},{"id":"oidc.discovery","title":"Fetch OIDC discovery metadata","summary":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","description":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect an issuer","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[]},{"id":"oidc.jwks","title":"Fetch a public JWKS","summary":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","description":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the exact JWKS URL.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"jwks_uri","type":"string","required":true,"description":"Exact HTTPS JWKS URL without credentials, a query, or a fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect issuer signing keys","args":{"jwks_uri":"https://accounts.example.com/keys"}}],"search_terms":[]},{"id":"oidc.jwt_header","title":"Decode a protected JWT header","summary":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","description":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","kind":"script","risk":"low","side_effects":["Local base64url and JSON decoding only.","The sensitive compact token is passed through environment, not argv, and is never emitted."],"args":[{"name":"jwt","type":"string","required":true,"sensitive":true,"description":"Compact JWS or JWE serialization.","validation":{"pattern":"^(?:[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*|[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$","max_length":16384}}],"examples":[{"title":"Inspect protected signing metadata","args":{"jwt":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImN1cnJlbnQifQ.e30.signature"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"alg":{"maxLength":64,"minLength":1,"type":"string"},"crit":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":["array","null"]},"cty":{"maxLength":128,"type":["string","null"]},"enc":{"maxLength":64,"type":["string","null"]},"jku":{"maxLength":512,"type":["string","null"]},"kid":{"maxLength":256,"type":["string","null"]},"present_fields":{"items":{"maxLength":8,"type":"string"},"maxItems":11,"type":"array"},"segment_count":{"enum":[3,5]},"serialization":{"enum":["jws","jwe"]},"typ":{"maxLength":64,"type":["string","null"]},"x5t":{"maxLength":64,"type":["string","null"]},"x5t_s256":{"maxLength":64,"type":["string","null"]},"x5u":{"maxLength":512,"type":["string","null"]},"zip":{"maxLength":32,"type":["string","null"]}},"required":["serialization","segment_count","alg","enc","kid","typ","cty","zip","crit","jku","x5u","x5t","x5t_s256","present_fields"],"type":"object"}},{"id":"oidc.validate_discovery","title":"Validate OIDC discovery metadata","summary":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","description":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Validate issuer metadata","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"discovery_url":{"type":"string"},"issuer":{"type":"string"},"jwks_uri":{"type":"string"},"valid":{"const":true}},"required":["valid","issuer","discovery_url","jwks_uri"],"type":"object"}}]},{"version":"0.1.3","content_hash":"sha256:35682d44a2971e21e08078cb3184448df26aff826da8b7b81787ced59da0ed87","tarball_url":"https://registry.emisar.dev/v1/packs/oidc-jwks/0.1.3/35682d44a2971e21e08078cb3184448df26aff826da8b7b81787ced59da0ed87/pack.tar.gz","actions":[{"id":"oidc.compare_key_ids","title":"Compare authoritative and consumer key IDs","summary":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","description":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","kind":"script","risk":"low","side_effects":["Local JSON parsing only.","Does not perform network or filesystem I/O."],"args":[{"name":"authoritative_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs from the authoritative JWKS.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}},{"name":"consumer_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs observed by the consumer.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}}],"examples":[{"title":"Detect a stale consumer","args":{"authoritative_key_ids_json":"[\"current\",\"next\"]","consumer_key_ids_json":"[\"current\",\"old\"]"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"authoritative_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_covers_authoritative":{"type":"boolean"},"exact_match":{"type":"boolean"},"extra_count":{"maximum":128,"minimum":0,"type":"integer"},"extra_in_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"missing_count":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"relation":{"enum":["equal","consumer_missing","consumer_extra","consumer_missing_and_extra"]},"shared_count":{"maximum":128,"minimum":0,"type":"integer"},"truncated":{"additionalProperties":false,"properties":{"extra_in_consumer":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"maximum":128,"minimum":0,"type":"integer"}},"required":["missing_from_consumer","extra_in_consumer"],"type":"object"}},"required":["authoritative_count","consumer_count","shared_count","missing_count","extra_count","missing_from_consumer","extra_in_consumer","truncated","exact_match","consumer_covers_authoritative","relation"],"type":"object"}},{"id":"oidc.discovery","title":"Fetch OIDC discovery metadata","summary":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","description":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect an issuer","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[]},{"id":"oidc.jwks","title":"Fetch a public JWKS","summary":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","description":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the exact JWKS URL.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"jwks_uri","type":"string","required":true,"description":"Exact HTTPS JWKS URL without credentials, a query, or a fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect issuer signing keys","args":{"jwks_uri":"https://accounts.example.com/keys"}}],"search_terms":[]},{"id":"oidc.jwt_header","title":"Decode a protected JWT header","summary":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","description":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","kind":"script","risk":"low","side_effects":["Local base64url and JSON decoding only.","The sensitive compact token is passed through environment, not argv, and is never emitted."],"args":[{"name":"jwt","type":"string","required":true,"sensitive":true,"description":"Compact JWS or JWE serialization.","validation":{"pattern":"^(?:[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*|[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$","max_length":16384}}],"examples":[{"title":"Inspect protected signing metadata","args":{"jwt":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImN1cnJlbnQifQ.e30.signature"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"alg":{"maxLength":64,"minLength":1,"type":"string"},"crit":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":["array","null"]},"cty":{"maxLength":128,"type":["string","null"]},"enc":{"maxLength":64,"type":["string","null"]},"jku":{"maxLength":512,"type":["string","null"]},"kid":{"maxLength":256,"type":["string","null"]},"present_fields":{"items":{"maxLength":8,"type":"string"},"maxItems":11,"type":"array"},"segment_count":{"enum":[3,5]},"serialization":{"enum":["jws","jwe"]},"typ":{"maxLength":64,"type":["string","null"]},"x5t":{"maxLength":64,"type":["string","null"]},"x5t_s256":{"maxLength":64,"type":["string","null"]},"x5u":{"maxLength":512,"type":["string","null"]},"zip":{"maxLength":32,"type":["string","null"]}},"required":["serialization","segment_count","alg","enc","kid","typ","cty","zip","crit","jku","x5u","x5t","x5t_s256","present_fields"],"type":"object"}},{"id":"oidc.validate_discovery","title":"Validate OIDC discovery metadata","summary":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","description":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Validate issuer metadata","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"discovery_url":{"type":"string"},"issuer":{"type":"string"},"jwks_uri":{"type":"string"},"valid":{"const":true}},"required":["valid","issuer","discovery_url","jwks_uri"],"type":"object"}}]},{"version":"0.1.2","content_hash":"sha256:cf1a74b9bf46b642c96c7fda81aefe612ccd1ae74be0dfc6ecf846b4dc68f98d","tarball_url":"https://registry.emisar.dev/v1/packs/oidc-jwks/0.1.2/cf1a74b9bf46b642c96c7fda81aefe612ccd1ae74be0dfc6ecf846b4dc68f98d/pack.tar.gz","actions":[{"id":"oidc.compare_key_ids","title":"Compare authoritative and consumer key IDs","summary":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","description":"Compare two bounded JSON arrays of public key IDs and report exact counts of shared, missing, and extra IDs plus capped, clipped samples of the missing and extra ones. Inputs are sorted and deduplicated before comparison.","kind":"script","risk":"low","side_effects":["Local JSON parsing only.","Does not perform network or filesystem I/O."],"args":[{"name":"authoritative_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs from the authoritative JWKS.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}},{"name":"consumer_key_ids_json","type":"string","required":true,"description":"JSON array of key IDs observed by the consumer.","validation":{"pattern":"^\\[[ -~]*\\]$","max_length":16384}}],"examples":[{"title":"Detect a stale consumer","args":{"authoritative_key_ids_json":"[\"current\",\"next\"]","consumer_key_ids_json":"[\"current\",\"old\"]"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"authoritative_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_count":{"maximum":128,"minimum":0,"type":"integer"},"consumer_covers_authoritative":{"type":"boolean"},"exact_match":{"type":"boolean"},"extra_count":{"maximum":128,"minimum":0,"type":"integer"},"extra_in_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"missing_count":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":"array"},"relation":{"enum":["equal","consumer_missing","consumer_extra","consumer_missing_and_extra"]},"shared_count":{"maximum":128,"minimum":0,"type":"integer"},"truncated":{"additionalProperties":false,"properties":{"extra_in_consumer":{"maximum":128,"minimum":0,"type":"integer"},"missing_from_consumer":{"maximum":128,"minimum":0,"type":"integer"}},"required":["missing_from_consumer","extra_in_consumer"],"type":"object"}},"required":["authoritative_count","consumer_count","shared_count","missing_count","extra_count","missing_from_consumer","extra_in_consumer","truncated","exact_match","consumer_covers_authoritative","relation"],"type":"object"}},{"id":"oidc.discovery","title":"Fetch OIDC discovery metadata","summary":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","description":"Fetch and return the public OpenID Provider Configuration for one exact HTTPS issuer. Redirects are rejected and advertised URLs are not followed.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect an issuer","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[]},{"id":"oidc.jwks","title":"Fetch a public JWKS","summary":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","description":"Fetch and validate one explicit public JWKS. The action rejects redirects, oversized key sets, malformed keys, and private or symmetric key material.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the exact JWKS URL.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"jwks_uri","type":"string","required":true,"description":"Exact HTTPS JWKS URL without credentials, a query, or a fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Inspect issuer signing keys","args":{"jwks_uri":"https://accounts.example.com/keys"}}],"search_terms":[]},{"id":"oidc.jwt_header","title":"Decode a protected JWT header","summary":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","description":"Decode and project recognized fields from a compact JWS or JWE protected header. The payload and claims are never decoded, and no signature or claim validation is performed. Recognized fields are byte-bounded; a header whose field exceeds its bound or carries control characters is rejected.","kind":"script","risk":"low","side_effects":["Local base64url and JSON decoding only.","The sensitive compact token is passed through environment, not argv, and is never emitted."],"args":[{"name":"jwt","type":"string","required":true,"sensitive":true,"description":"Compact JWS or JWE serialization.","validation":{"pattern":"^(?:[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]*|[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)$","max_length":16384}}],"examples":[{"title":"Inspect protected signing metadata","args":{"jwt":"eyJhbGciOiJSUzI1NiIsImtpZCI6ImN1cnJlbnQifQ.e30.signature"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"alg":{"maxLength":64,"minLength":1,"type":"string"},"crit":{"items":{"maxLength":64,"type":"string"},"maxItems":16,"type":["array","null"]},"cty":{"maxLength":128,"type":["string","null"]},"enc":{"maxLength":64,"type":["string","null"]},"jku":{"maxLength":512,"type":["string","null"]},"kid":{"maxLength":256,"type":["string","null"]},"present_fields":{"items":{"maxLength":8,"type":"string"},"maxItems":11,"type":"array"},"segment_count":{"enum":[3,5]},"serialization":{"enum":["jws","jwe"]},"typ":{"maxLength":64,"type":["string","null"]},"x5t":{"maxLength":64,"type":["string","null"]},"x5t_s256":{"maxLength":64,"type":["string","null"]},"x5u":{"maxLength":512,"type":["string","null"]},"zip":{"maxLength":32,"type":["string","null"]}},"required":["serialization","segment_count","alg","enc","kid","typ","cty","zip","crit","jku","x5u","x5t","x5t_s256","present_fields"],"type":"object"}},{"id":"oidc.validate_discovery","title":"Validate OIDC discovery metadata","summary":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","description":"Require an exact issuer match and an accepted HTTPS jwks_uri in one discovery document. This action does not fetch the advertised JWKS.","kind":"script","risk":"low","side_effects":["One unauthenticated HTTPS GET to the issuer's discovery endpoint.","Writes the public response to a mode-0600 temporary file and removes it before exit."],"args":[{"name":"issuer","type":"string","required":true,"description":"Exact HTTPS issuer URL without a query or fragment.","validation":{"pattern":"^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?(?:/[A-Za-z0-9._~!$&'()*+,=:;%@/-]*)?$","max_length":768}}],"examples":[{"title":"Validate issuer metadata","args":{"issuer":"https://accounts.example.com"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"discovery_url":{"type":"string"},"issuer":{"type":"string"},"jwks_uri":{"type":"string"},"valid":{"const":true}},"required":["valid","issuer","discovery_url","jwks_uri"],"type":"object"}}]}]},{"id":"pfsense","name":"pfSense firewall","version":"0.6.4","description":"Operate a pfSense firewall over its REST API: read firewall rules, NAT, aliases, virtual IPs, interface / gateway (config + status) / service / VPN status, DHCP leases, routes, ARP, CARP, pf tables, installed packages, the config-change history, and firewall / system / auth / DHCP / OpenVPN logs, plus a few gated mutators (apply filter, flush states, restart a service, reboot). Uses the community pfSense-pkg-RESTAPI package (/api/v2), which runs on the firewall and works across CE and Plus.","vendor":"emisar","homepage":"https://emisar.dev/packs/pfsense","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/pfsense","content_hash":"sha256:ec3586b324b54060b184673292325cfe0641e69e3dcfe3e9eed10ef1d77ba871","tarball_url":"https://registry.emisar.dev/v1/packs/pfsense/0.6.4/ec3586b324b54060b184673292325cfe0641e69e3dcfe3e9eed10ef1d77ba871/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Every action calls the pfSense REST API at `$PFSENSE_URL` via curl, sending `$PFSENSE_API_KEY` as the X-API-Key header. Install the community pfSense-pkg-RESTAPI package on the firewall (System → Package Manager), mint a key under System → REST API → Keys, and point `PFSENSE_URL` at the firewall's GUI URL.","env":[{"name":"PFSENSE_URL","description":"Firewall GUI / API base URL — scheme, host, and port if non-default. The API is served on the same TLS + port as the webConfigurator.","default":"https://192.168.1.1","example":"https://fw1.internal"},{"name":"PFSENSE_API_KEY","required":true,"description":"REST API key (System → REST API → Keys). Sent as the X-API-Key header over curl stdin, so it never appears in the process arguments or the audit log. Use a least-privilege, read-only key."},{"name":"PFSENSE_INSECURE","description":"Set to \"true\" to skip TLS verification — needed for the default self-signed GUI certificate. Prefer pinning a CA via CURL_CA_BUNDLE."}],"notes":["Any of `PFSENSE_URL` / `PFSENSE_API_KEY` / `PFSENSE_INSECURE` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Requires the community REST API package (pfSense-pkg-RESTAPI, /api/v2) installed on the firewall — not Netgate's Nexus controller API. The package's read_only switch (System → REST API) forces the whole API GET-only; pair it with a read-only key for a diagnostics deployment.","TLS is verified by default. pfSense ships a self-signed GUI cert, so set `PFSENSE_INSECURE`=true, or set CURL_CA_BUNDLE to a CA file (curl reads it natively) to verify properly.","Reads that would expose secrets (user passwords, IPsec phase pre-shared keys) are intentionally omitted, and the API's arbitrary-command endpoint (/diagnostics/command_prompt — a remote shell) is deliberately not wired: that belongs in the default-denied `shell` break-glass pack, not here. The certificate-store reads (certificates / certificate_authorities / crls) select only non-secret fields with jq, so the certificate private key (`prv` PEM) is never returned — by design, not just redaction. The mutators are risk-gated; reboot is critical.","Dynamic routing (FRR — BGP / OSPF / BFD) is NOT exposed by this REST API, so this pack cannot read it. FRR state lives behind vtysh on the firewall; reach it out-of-band (the `frr` pack runs vtysh locally on an FRR host, or use SNMP)."],"verify":"pfsense.version"},"actions":[{"id":"pfsense.aliases","title":"GET /api/v2/firewall/aliases","summary":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","description":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All aliases","args":{}}],"search_terms":[]},{"id":"pfsense.apply_dhcp_server","title":"POST /api/v2/services/dhcp_server/apply","summary":"Apply staged DHCP server changes — reloads dhcpd so pending static-mapping or pool edits take effect. This is the separate step the static-mapping writes deliberately leave to the operator; it pushes whatever is currently staged, not only the change you just made.","description":"Apply staged DHCP server changes — reloads dhcpd so pending static-mapping or pool edits take effect. This is the separate step the static-mapping writes deliberately leave to the operator; it pushes whatever is currently staged, not only the change you just made.","kind":"script","risk":"medium","side_effects":["Reloads the DHCP server (brief).","Applies any staged DHCP configuration changes, including ones staged by someone else.","Existing leases are kept; clients pick up changes on renewal."],"args":[],"examples":[{"title":"Apply staged DHCP changes","args":{}}],"search_terms":[]},{"id":"pfsense.apply_filter","title":"POST /api/v2/firewall/apply","summary":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","description":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","kind":"script","risk":"medium","side_effects":["Reloads the firewall filter (brief).","Applies any staged firewall configuration changes to the live ruleset."],"args":[],"examples":[{"title":"Apply staged firewall changes","args":{}}],"search_terms":[]},{"id":"pfsense.arp_table","title":"GET /api/v2/diagnostics/arp_table","summary":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","description":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[]},{"id":"pfsense.auth_log","title":"GET /api/v2/status/logs/auth","summary":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","description":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 auth log lines","args":{}}],"search_terms":[]},{"id":"pfsense.carp_status","title":"GET /api/v2/status/carp","summary":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","description":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"CARP / HA state","args":{}}],"search_terms":[]},{"id":"pfsense.certificate_authorities","title":"GET /api/v2/system/certificate_authorities","summary":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","description":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate authorities","args":{}}],"search_terms":[]},{"id":"pfsense.certificates","title":"GET /api/v2/system/certificates","summary":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","description":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate store with expiry","args":{}}],"search_terms":[]},{"id":"pfsense.config_history","title":"GET /api/v2/diagnostics/config_history/revisions","summary":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","description":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configuration change history","args":{}}],"search_terms":[]},{"id":"pfsense.create_dhcp_static_mapping","title":"POST /api/v2/services/dhcp_server/static_mapping","summary":"Reserve one DHCP address for one MAC on one interface — the \"give this host a stable address\" edit. Creates a single mapping; it never touches an existing one and never edits a pool. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs, so the operator chooses when the DHCP server reloads.","description":"Reserve one DHCP address for one MAC on one interface — the \"give this host a stable address\" edit. Creates a single mapping; it never touches an existing one and never edits a pool. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs, so the operator chooses when the DHCP server reloads.","kind":"script","risk":"medium","side_effects":["Adds one static mapping to the named interface's DHCP server.","Staged only — dhcpd is not reloaded, so nothing changes for clients yet.","The reserved address must be outside the interface's DHCP pool range; the API rejects the write otherwise."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}},{"name":"mac","type":"string","required":true,"description":"MAC address of the client, colon-separated.","validation":{"pattern":"^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$"}},{"name":"ipaddr","type":"string","required":true,"description":"IPv4 address to reserve. Must be in the interface subnet and outside its pool.","validation":{"pattern":"^([0-9]{1,3}\\.){3}[0-9]{1,3}$"}},{"name":"hostname","type":"string","required":false,"default":"","description":"Hostname to hand the client. Empty leaves it unset.","validation":{"pattern":"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)?$"}},{"name":"description","type":"string","required":false,"default":"","description":"Free-text note stored with the mapping.","validation":{"pattern":"^[A-Za-z0-9 ._@()-]{0,128}$"}}],"examples":[{"title":"Reserve an address for a printer","args":{"description":"Floor 2 printer","hostname":"printer","interface":"lan","ipaddr":"192.168.1.20","mac":"00:1b:44:11:3a:b7"}}],"search_terms":[]},{"id":"pfsense.crls","title":"GET /api/v2/system/crls","summary":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","description":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate revocation lists","args":{}}],"search_terms":[]},{"id":"pfsense.delete_dhcp_static_mapping","title":"DELETE /api/v2/services/dhcp_server/static_mapping","summary":"Remove one DHCP static mapping, named by the interface and the id that pfsense.dhcp_static_mappings returns for it. Deletes exactly that one mapping — there is no wildcard form and no \"delete all\" here. The client falls back to a pool address on its next lease. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs.","description":"Remove one DHCP static mapping, named by the interface and the id that pfsense.dhcp_static_mappings returns for it. Deletes exactly that one mapping — there is no wildcard form and no \"delete all\" here. The client falls back to a pool address on its next lease. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs.","kind":"script","risk":"medium","side_effects":["Removes one static mapping from the named interface's DHCP server.","Staged only — dhcpd is not reloaded, so the client keeps its current lease.","The host loses its reserved address and takes a pool address on renewal."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}},{"name":"id","type":"integer","required":true,"description":"The mapping id from pfsense.dhcp_static_mappings on this interface.","validation":{"min":0,"max":65535}}],"examples":[{"title":"Drop the mapping listed as id 3 on LAN","args":{"id":3,"interface":"lan"}}],"search_terms":[]},{"id":"pfsense.dhcp_leases","title":"GET /api/v2/status/dhcp_server/leases","summary":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","description":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"DHCP leases","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_log","title":"GET /api/v2/status/logs/dhcp","summary":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","description":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 DHCP log lines","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_static_mappings","title":"GET /api/v2/services/dhcp_server/static_mappings","summary":"List the DHCP static mappings on one interface — each mapping's id, MAC, reserved address, hostname, description, and whether it also gets a static ARP entry. This is the read that names the object every static-mapping write acts on: the delete takes the id this returns.","description":"List the DHCP static mappings on one interface — each mapping's id, MAC, reserved address, hostname, description, and whether it also gets a static ARP entry. This is the read that names the object every static-mapping write acts on: the delete takes the id this returns.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}}],"examples":[{"title":"Static mappings on LAN","args":{"interface":"lan"}}],"search_terms":[]},{"id":"pfsense.dns_resolver_settings","title":"GET /api/v2/services/dns_resolver/settings","summary":"Show the DNS Resolver (Unbound) configuration — whether it is enabled, the listen and TLS ports, the interfaces it binds and forwards out of, DNSSEC and forwarding mode, and the DHCP/OpenVPN registration flags. The operator's free-text `custom_options` block is never returned: it is raw Unbound config an operator can put anything in, including forwarding credentials, so the action selects only the settings above and drops it at the source.","description":"Show the DNS Resolver (Unbound) configuration — whether it is enabled, the listen and TLS ports, the interfaces it binds and forwards out of, DNSSEC and forwarding mode, and the DHCP/OpenVPN registration flags. The operator's free-text `custom_options` block is never returned: it is raw Unbound config an operator can put anything in, including forwarding credentials, so the action selects only the settings above and drops it at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Resolver configuration","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_log","title":"GET /api/v2/status/logs/firewall","summary":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","description":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 firewall log lines","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_rules","title":"GET /api/v2/firewall/rules","summary":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","description":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All filter rules","args":{}}],"search_terms":[]},{"id":"pfsense.flush_states","title":"DELETE /api/v2/firewall/states","summary":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","description":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","kind":"script","risk":"high","side_effects":["Clears the entire pf state table.","Every active connection through the firewall is dropped and must reconnect."],"args":[],"examples":[{"title":"Flush the state table","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_groups","title":"GET /api/v2/routing/gateway/groups","summary":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","description":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway groups","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_status","title":"GET /api/v2/status/gateways","summary":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","description":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway health","args":{}}],"search_terms":[]},{"id":"pfsense.gateways","title":"GET /api/v2/routing/gateways","summary":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","description":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured gateways","args":{}}],"search_terms":[]},{"id":"pfsense.interface_config","title":"GET /api/v2/interfaces","summary":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","description":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All interface configuration","args":{}}],"search_terms":[]},{"id":"pfsense.interface_status","title":"GET /api/v2/status/interfaces","summary":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","description":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_child_sas","title":"GET /api/v2/status/ipsec/child_sas","summary":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","description":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec child SAs","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_status","title":"GET /api/v2/status/ipsec/sas","summary":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","description":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec SAs","args":{}}],"search_terms":[]},{"id":"pfsense.nat_outbound","title":"GET /api/v2/firewall/nat/outbound/mappings","summary":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","description":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Outbound NAT","args":{}}],"search_terms":[]},{"id":"pfsense.nat_port_forwards","title":"GET /api/v2/firewall/nat/port_forwards","summary":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","description":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Port forwards","args":{}}],"search_terms":[]},{"id":"pfsense.ntp_settings","title":"GET /api/v2/services/ntp/settings","summary":"Show the NTP service configuration — whether it is enabled, the interfaces it binds, the poll interval bounds, orphan-mode stratum, peer limit, logging and statistics flags, leap-second handling, and whether server authentication is on with which algorithm. The shared authentication key itself is never returned: the action selects only the settings above, so `serverauthkey` is dropped at the source.","description":"Show the NTP service configuration — whether it is enabled, the interfaces it binds, the poll interval bounds, orphan-mode stratum, peer limit, logging and statistics flags, leap-second handling, and whether server authentication is on with which algorithm. The shared authentication key itself is never returned: the action selects only the settings above, so `serverauthkey` is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"NTP configuration","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_log","title":"GET /api/v2/status/logs/openvpn","summary":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","description":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 OpenVPN log lines","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_status","title":"GET /api/v2/status/openvpn/servers","summary":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","description":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"OpenVPN status","args":{}}],"search_terms":[]},{"id":"pfsense.pf_table","title":"GET /api/v2/diagnostics/table","summary":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","description":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"pf table name (from pfsense.pf_tables), e.g. sshguard, bogons, virusprot.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}}],"examples":[{"title":"Addresses sshguard is blocking","args":{"name":"sshguard"}}],"search_terms":[]},{"id":"pfsense.pf_tables","title":"GET /api/v2/diagnostics/tables","summary":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","description":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All pf table names","args":{}}],"search_terms":[]},{"id":"pfsense.reboot","title":"POST /api/v2/diagnostics/reboot","summary":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","description":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","kind":"script","risk":"critical","side_effects":["Reboots the firewall.","All traffic through the firewall stops until the boot completes."],"args":[],"examples":[{"title":"Reboot the firewall","args":{}}],"search_terms":[]},{"id":"pfsense.restart_service","title":"POST /api/v2/status/service (restart)","summary":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","description":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","kind":"script","risk":"high","side_effects":["Restarts the named service.","The service is briefly unavailable; dependent connectivity may drop."],"args":[{"name":"service","type":"string","required":true,"description":"Service name as listed by service_status, e.g. unbound, openvpn, ipsec.","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}$"}}],"examples":[{"title":"Restart the DNS Resolver","args":{"service":"unbound"}}],"search_terms":[]},{"id":"pfsense.service_status","title":"GET /api/v2/status/services","summary":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","description":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Service status","args":{}}],"search_terms":[]},{"id":"pfsense.states_size","title":"GET /api/v2/firewall/states/size","summary":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","description":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"State table count vs max","args":{}}],"search_terms":[]},{"id":"pfsense.static_routes","title":"GET /api/v2/routing/static_routes","summary":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","description":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Static routes","args":{}}],"search_terms":[]},{"id":"pfsense.system_log","title":"GET /api/v2/status/logs/system","summary":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","description":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 system log lines","args":{}}],"search_terms":[]},{"id":"pfsense.system_packages","title":"GET /api/v2/system/packages","summary":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","description":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Installed packages","args":{}}],"search_terms":[]},{"id":"pfsense.system_status","title":"GET /api/v2/status/system","summary":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","description":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"System health","args":{}}],"search_terms":[]},{"id":"pfsense.version","title":"GET /api/v2/system/version","summary":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","description":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[]},{"id":"pfsense.virtual_ips","title":"GET /api/v2/firewall/virtual_ips","summary":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","description":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All virtual IPs","args":{}}],"search_terms":[]},{"id":"pfsense.wireguard_peers","title":"GET /api/v2/vpn/wireguard/peers","summary":"List the configured WireGuard peers — each peer's description, whether it is enabled, the tunnel it belongs to, its endpoint host and port, keepalive interval, public key, and allowed IPs, for answering \"is this peer configured and pointed where I think it is\". The peer's optional pre-shared key is never returned: the action selects only the fields above, so `presharedkey` is dropped at the source.","description":"List the configured WireGuard peers — each peer's description, whether it is enabled, the tunnel it belongs to, its endpoint host and port, keepalive interval, public key, and allowed IPs, for answering \"is this peer configured and pointed where I think it is\". The peer's optional pre-shared key is never returned: the action selects only the fields above, so `presharedkey` is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured peers","args":{}}],"search_terms":[]}],"previous_versions":[{"version":"0.6.2","content_hash":"sha256:9efeb854b9bf0e7e958b6ef81d7b92b92eb87db5b847e10dc642b9179995ee78","tarball_url":"https://registry.emisar.dev/v1/packs/pfsense/0.6.2/9efeb854b9bf0e7e958b6ef81d7b92b92eb87db5b847e10dc642b9179995ee78/pack.tar.gz","actions":[{"id":"pfsense.aliases","title":"GET /api/v2/firewall/aliases","summary":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","description":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All aliases","args":{}}],"search_terms":[]},{"id":"pfsense.apply_dhcp_server","title":"POST /api/v2/services/dhcp_server/apply","summary":"Apply staged DHCP server changes — reloads dhcpd so pending static-mapping or pool edits take effect. This is the separate step the static-mapping writes deliberately leave to the operator; it pushes whatever is currently staged, not only the change you just made.","description":"Apply staged DHCP server changes — reloads dhcpd so pending static-mapping or pool edits take effect. This is the separate step the static-mapping writes deliberately leave to the operator; it pushes whatever is currently staged, not only the change you just made.","kind":"script","risk":"medium","side_effects":["Reloads the DHCP server (brief).","Applies any staged DHCP configuration changes, including ones staged by someone else.","Existing leases are kept; clients pick up changes on renewal."],"args":[],"examples":[{"title":"Apply staged DHCP changes","args":{}}],"search_terms":[]},{"id":"pfsense.apply_filter","title":"POST /api/v2/firewall/apply","summary":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","description":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","kind":"script","risk":"medium","side_effects":["Reloads the firewall filter (brief).","Applies any staged firewall configuration changes to the live ruleset."],"args":[],"examples":[{"title":"Apply staged firewall changes","args":{}}],"search_terms":[]},{"id":"pfsense.arp_table","title":"GET /api/v2/diagnostics/arp_table","summary":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","description":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[]},{"id":"pfsense.auth_log","title":"GET /api/v2/status/logs/auth","summary":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","description":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 auth log lines","args":{}}],"search_terms":[]},{"id":"pfsense.carp_status","title":"GET /api/v2/status/carp","summary":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","description":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"CARP / HA state","args":{}}],"search_terms":[]},{"id":"pfsense.certificate_authorities","title":"GET /api/v2/system/certificate_authorities","summary":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","description":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate authorities","args":{}}],"search_terms":[]},{"id":"pfsense.certificates","title":"GET /api/v2/system/certificates","summary":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","description":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate store with expiry","args":{}}],"search_terms":[]},{"id":"pfsense.config_history","title":"GET /api/v2/diagnostics/config_history/revisions","summary":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","description":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configuration change history","args":{}}],"search_terms":[]},{"id":"pfsense.create_dhcp_static_mapping","title":"POST /api/v2/services/dhcp_server/static_mapping","summary":"Reserve one DHCP address for one MAC on one interface — the \"give this host a stable address\" edit. Creates a single mapping; it never touches an existing one and never edits a pool. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs, so the operator chooses when the DHCP server reloads.","description":"Reserve one DHCP address for one MAC on one interface — the \"give this host a stable address\" edit. Creates a single mapping; it never touches an existing one and never edits a pool. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs, so the operator chooses when the DHCP server reloads.","kind":"script","risk":"medium","side_effects":["Adds one static mapping to the named interface's DHCP server.","Staged only — dhcpd is not reloaded, so nothing changes for clients yet.","The reserved address must be outside the interface's DHCP pool range; the API rejects the write otherwise."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}},{"name":"mac","type":"string","required":true,"description":"MAC address of the client, colon-separated.","validation":{"pattern":"^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$"}},{"name":"ipaddr","type":"string","required":true,"description":"IPv4 address to reserve. Must be in the interface subnet and outside its pool.","validation":{"pattern":"^([0-9]{1,3}\\.){3}[0-9]{1,3}$"}},{"name":"hostname","type":"string","required":false,"default":"","description":"Hostname to hand the client. Empty leaves it unset.","validation":{"pattern":"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)?$"}},{"name":"description","type":"string","required":false,"default":"","description":"Free-text note stored with the mapping.","validation":{"pattern":"^[A-Za-z0-9 ._@()-]{0,128}$"}}],"examples":[{"title":"Reserve an address for a printer","args":{"description":"Floor 2 printer","hostname":"printer","interface":"lan","ipaddr":"192.168.1.20","mac":"00:1b:44:11:3a:b7"}}],"search_terms":[]},{"id":"pfsense.crls","title":"GET /api/v2/system/crls","summary":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","description":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate revocation lists","args":{}}],"search_terms":[]},{"id":"pfsense.delete_dhcp_static_mapping","title":"DELETE /api/v2/services/dhcp_server/static_mapping","summary":"Remove one DHCP static mapping, named by the interface and the id that pfsense.dhcp_static_mappings returns for it. Deletes exactly that one mapping — there is no wildcard form and no \"delete all\" here. The client falls back to a pool address on its next lease. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs.","description":"Remove one DHCP static mapping, named by the interface and the id that pfsense.dhcp_static_mappings returns for it. Deletes exactly that one mapping — there is no wildcard form and no \"delete all\" here. The client falls back to a pool address on its next lease. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs.","kind":"script","risk":"medium","side_effects":["Removes one static mapping from the named interface's DHCP server.","Staged only — dhcpd is not reloaded, so the client keeps its current lease.","The host loses its reserved address and takes a pool address on renewal."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}},{"name":"id","type":"integer","required":true,"description":"The mapping id from pfsense.dhcp_static_mappings on this interface.","validation":{"min":0,"max":65535}}],"examples":[{"title":"Drop the mapping listed as id 3 on LAN","args":{"id":3,"interface":"lan"}}],"search_terms":[]},{"id":"pfsense.dhcp_leases","title":"GET /api/v2/status/dhcp_server/leases","summary":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","description":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"DHCP leases","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_log","title":"GET /api/v2/status/logs/dhcp","summary":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","description":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 DHCP log lines","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_static_mappings","title":"GET /api/v2/services/dhcp_server/static_mappings","summary":"List the DHCP static mappings on one interface — each mapping's id, MAC, reserved address, hostname, description, and whether it also gets a static ARP entry. This is the read that names the object every static-mapping write acts on: the delete takes the id this returns.","description":"List the DHCP static mappings on one interface — each mapping's id, MAC, reserved address, hostname, description, and whether it also gets a static ARP entry. This is the read that names the object every static-mapping write acts on: the delete takes the id this returns.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}}],"examples":[{"title":"Static mappings on LAN","args":{"interface":"lan"}}],"search_terms":[]},{"id":"pfsense.dns_resolver_settings","title":"GET /api/v2/services/dns_resolver/settings","summary":"Show the DNS Resolver (Unbound) configuration — whether it is enabled, the listen and TLS ports, the interfaces it binds and forwards out of, DNSSEC and forwarding mode, and the DHCP/OpenVPN registration flags. The operator's free-text `custom_options` block is never returned: it is raw Unbound config an operator can put anything in, including forwarding credentials, so the action selects only the settings above and drops it at the source.","description":"Show the DNS Resolver (Unbound) configuration — whether it is enabled, the listen and TLS ports, the interfaces it binds and forwards out of, DNSSEC and forwarding mode, and the DHCP/OpenVPN registration flags. The operator's free-text `custom_options` block is never returned: it is raw Unbound config an operator can put anything in, including forwarding credentials, so the action selects only the settings above and drops it at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Resolver configuration","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_log","title":"GET /api/v2/status/logs/firewall","summary":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","description":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 firewall log lines","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_rules","title":"GET /api/v2/firewall/rules","summary":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","description":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All filter rules","args":{}}],"search_terms":[]},{"id":"pfsense.flush_states","title":"DELETE /api/v2/firewall/states","summary":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","description":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","kind":"script","risk":"high","side_effects":["Clears the entire pf state table.","Every active connection through the firewall is dropped and must reconnect."],"args":[],"examples":[{"title":"Flush the state table","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_groups","title":"GET /api/v2/routing/gateway/groups","summary":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","description":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway groups","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_status","title":"GET /api/v2/status/gateways","summary":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","description":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway health","args":{}}],"search_terms":[]},{"id":"pfsense.gateways","title":"GET /api/v2/routing/gateways","summary":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","description":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured gateways","args":{}}],"search_terms":[]},{"id":"pfsense.interface_config","title":"GET /api/v2/interfaces","summary":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","description":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All interface configuration","args":{}}],"search_terms":[]},{"id":"pfsense.interface_status","title":"GET /api/v2/status/interfaces","summary":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","description":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_child_sas","title":"GET /api/v2/status/ipsec/child_sas","summary":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","description":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec child SAs","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_status","title":"GET /api/v2/status/ipsec/sas","summary":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","description":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec SAs","args":{}}],"search_terms":[]},{"id":"pfsense.nat_outbound","title":"GET /api/v2/firewall/nat/outbound/mappings","summary":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","description":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Outbound NAT","args":{}}],"search_terms":[]},{"id":"pfsense.nat_port_forwards","title":"GET /api/v2/firewall/nat/port_forwards","summary":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","description":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Port forwards","args":{}}],"search_terms":[]},{"id":"pfsense.ntp_settings","title":"GET /api/v2/services/ntp/settings","summary":"Show the NTP service configuration — whether it is enabled, the interfaces it binds, the poll interval bounds, orphan-mode stratum, peer limit, logging and statistics flags, leap-second handling, and whether server authentication is on with which algorithm. The shared authentication key itself is never returned: the action selects only the settings above, so `serverauthkey` is dropped at the source.","description":"Show the NTP service configuration — whether it is enabled, the interfaces it binds, the poll interval bounds, orphan-mode stratum, peer limit, logging and statistics flags, leap-second handling, and whether server authentication is on with which algorithm. The shared authentication key itself is never returned: the action selects only the settings above, so `serverauthkey` is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"NTP configuration","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_log","title":"GET /api/v2/status/logs/openvpn","summary":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","description":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 OpenVPN log lines","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_status","title":"GET /api/v2/status/openvpn/servers","summary":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","description":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"OpenVPN status","args":{}}],"search_terms":[]},{"id":"pfsense.pf_table","title":"GET /api/v2/diagnostics/table","summary":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","description":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"pf table name (from pfsense.pf_tables), e.g. sshguard, bogons, virusprot.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}}],"examples":[{"title":"Addresses sshguard is blocking","args":{"name":"sshguard"}}],"search_terms":[]},{"id":"pfsense.pf_tables","title":"GET /api/v2/diagnostics/tables","summary":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","description":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All pf table names","args":{}}],"search_terms":[]},{"id":"pfsense.reboot","title":"POST /api/v2/diagnostics/reboot","summary":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","description":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","kind":"script","risk":"critical","side_effects":["Reboots the firewall.","All traffic through the firewall stops until the boot completes."],"args":[],"examples":[{"title":"Reboot the firewall","args":{}}],"search_terms":[]},{"id":"pfsense.restart_service","title":"POST /api/v2/status/service (restart)","summary":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","description":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","kind":"script","risk":"high","side_effects":["Restarts the named service.","The service is briefly unavailable; dependent connectivity may drop."],"args":[{"name":"service","type":"string","required":true,"description":"Service name as listed by service_status, e.g. unbound, openvpn, ipsec.","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}$"}}],"examples":[{"title":"Restart the DNS Resolver","args":{"service":"unbound"}}],"search_terms":[]},{"id":"pfsense.service_status","title":"GET /api/v2/status/services","summary":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","description":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Service status","args":{}}],"search_terms":[]},{"id":"pfsense.states_size","title":"GET /api/v2/firewall/states/size","summary":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","description":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"State table count vs max","args":{}}],"search_terms":[]},{"id":"pfsense.static_routes","title":"GET /api/v2/routing/static_routes","summary":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","description":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Static routes","args":{}}],"search_terms":[]},{"id":"pfsense.system_log","title":"GET /api/v2/status/logs/system","summary":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","description":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 system log lines","args":{}}],"search_terms":[]},{"id":"pfsense.system_packages","title":"GET /api/v2/system/packages","summary":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","description":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Installed packages","args":{}}],"search_terms":[]},{"id":"pfsense.system_status","title":"GET /api/v2/status/system","summary":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","description":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"System health","args":{}}],"search_terms":[]},{"id":"pfsense.version","title":"GET /api/v2/system/version","summary":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","description":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[]},{"id":"pfsense.virtual_ips","title":"GET /api/v2/firewall/virtual_ips","summary":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","description":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All virtual IPs","args":{}}],"search_terms":[]},{"id":"pfsense.wireguard_peers","title":"GET /api/v2/vpn/wireguard/peers","summary":"List the configured WireGuard peers — each peer's description, whether it is enabled, the tunnel it belongs to, its endpoint host and port, keepalive interval, public key, and allowed IPs, for answering \"is this peer configured and pointed where I think it is\". The peer's optional pre-shared key is never returned: the action selects only the fields above, so `presharedkey` is dropped at the source.","description":"List the configured WireGuard peers — each peer's description, whether it is enabled, the tunnel it belongs to, its endpoint host and port, keepalive interval, public key, and allowed IPs, for answering \"is this peer configured and pointed where I think it is\". The peer's optional pre-shared key is never returned: the action selects only the fields above, so `presharedkey` is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured peers","args":{}}],"search_terms":[]}]},{"version":"0.6.0","content_hash":"sha256:6eb86110e4dda190b0311e8e0e4ff46ca50e7ec1a8dbd70d5246061823905169","tarball_url":"https://registry.emisar.dev/v1/packs/pfsense/0.6.0/6eb86110e4dda190b0311e8e0e4ff46ca50e7ec1a8dbd70d5246061823905169/pack.tar.gz","actions":[{"id":"pfsense.aliases","title":"GET /api/v2/firewall/aliases","summary":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","description":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All aliases","args":{}}],"search_terms":[]},{"id":"pfsense.apply_dhcp_server","title":"POST /api/v2/services/dhcp_server/apply","summary":"Apply staged DHCP server changes — reloads dhcpd so pending static-mapping or pool edits take effect. This is the separate step the static-mapping writes deliberately leave to the operator; it pushes whatever is currently staged, not only the change you just made.","description":"Apply staged DHCP server changes — reloads dhcpd so pending static-mapping or pool edits take effect. This is the separate step the static-mapping writes deliberately leave to the operator; it pushes whatever is currently staged, not only the change you just made.","kind":"script","risk":"medium","side_effects":["Reloads the DHCP server (brief).","Applies any staged DHCP configuration changes, including ones staged by someone else.","Existing leases are kept; clients pick up changes on renewal."],"args":[],"examples":[{"title":"Apply staged DHCP changes","args":{}}],"search_terms":[]},{"id":"pfsense.apply_filter","title":"POST /api/v2/firewall/apply","summary":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","description":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","kind":"script","risk":"medium","side_effects":["Reloads the firewall filter (brief).","Applies any staged firewall configuration changes to the live ruleset."],"args":[],"examples":[{"title":"Apply staged firewall changes","args":{}}],"search_terms":[]},{"id":"pfsense.arp_table","title":"GET /api/v2/diagnostics/arp_table","summary":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","description":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[]},{"id":"pfsense.auth_log","title":"GET /api/v2/status/logs/auth","summary":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","description":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 auth log lines","args":{}}],"search_terms":[]},{"id":"pfsense.carp_status","title":"GET /api/v2/status/carp","summary":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","description":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"CARP / HA state","args":{}}],"search_terms":[]},{"id":"pfsense.certificate_authorities","title":"GET /api/v2/system/certificate_authorities","summary":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","description":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate authorities","args":{}}],"search_terms":[]},{"id":"pfsense.certificates","title":"GET /api/v2/system/certificates","summary":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","description":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate store with expiry","args":{}}],"search_terms":[]},{"id":"pfsense.config_history","title":"GET /api/v2/diagnostics/config_history/revisions","summary":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","description":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configuration change history","args":{}}],"search_terms":[]},{"id":"pfsense.create_dhcp_static_mapping","title":"POST /api/v2/services/dhcp_server/static_mapping","summary":"Reserve one DHCP address for one MAC on one interface — the \"give this host a stable address\" edit. Creates a single mapping; it never touches an existing one and never edits a pool. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs, so the operator chooses when the DHCP server reloads.","description":"Reserve one DHCP address for one MAC on one interface — the \"give this host a stable address\" edit. Creates a single mapping; it never touches an existing one and never edits a pool. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs, so the operator chooses when the DHCP server reloads.","kind":"script","risk":"medium","side_effects":["Adds one static mapping to the named interface's DHCP server.","Staged only — dhcpd is not reloaded, so nothing changes for clients yet.","The reserved address must be outside the interface's DHCP pool range; the API rejects the write otherwise."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}},{"name":"mac","type":"string","required":true,"description":"MAC address of the client, colon-separated.","validation":{"pattern":"^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$"}},{"name":"ipaddr","type":"string","required":true,"description":"IPv4 address to reserve. Must be in the interface subnet and outside its pool.","validation":{"pattern":"^([0-9]{1,3}\\.){3}[0-9]{1,3}$"}},{"name":"hostname","type":"string","required":false,"default":"","description":"Hostname to hand the client. Empty leaves it unset.","validation":{"pattern":"^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)?$"}},{"name":"description","type":"string","required":false,"default":"","description":"Free-text note stored with the mapping.","validation":{"pattern":"^[A-Za-z0-9 ._@()-]{0,128}$"}}],"examples":[{"title":"Reserve an address for a printer","args":{"description":"Floor 2 printer","hostname":"printer","interface":"lan","ipaddr":"192.168.1.20","mac":"00:1b:44:11:3a:b7"}}],"search_terms":[]},{"id":"pfsense.crls","title":"GET /api/v2/system/crls","summary":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","description":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate revocation lists","args":{}}],"search_terms":[]},{"id":"pfsense.delete_dhcp_static_mapping","title":"DELETE /api/v2/services/dhcp_server/static_mapping","summary":"Remove one DHCP static mapping, named by the interface and the id that pfsense.dhcp_static_mappings returns for it. Deletes exactly that one mapping — there is no wildcard form and no \"delete all\" here. The client falls back to a pool address on its next lease. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs.","description":"Remove one DHCP static mapping, named by the interface and the id that pfsense.dhcp_static_mappings returns for it. Deletes exactly that one mapping — there is no wildcard form and no \"delete all\" here. The client falls back to a pool address on its next lease. The change is STAGED: dhcpd keeps serving the old configuration until pfsense.apply_dhcp_server runs.","kind":"script","risk":"medium","side_effects":["Removes one static mapping from the named interface's DHCP server.","Staged only — dhcpd is not reloaded, so the client keeps its current lease.","The host loses its reserved address and takes a pool address on renewal."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}},{"name":"id","type":"integer","required":true,"description":"The mapping id from pfsense.dhcp_static_mappings on this interface.","validation":{"min":0,"max":65535}}],"examples":[{"title":"Drop the mapping listed as id 3 on LAN","args":{"id":3,"interface":"lan"}}],"search_terms":[]},{"id":"pfsense.dhcp_leases","title":"GET /api/v2/status/dhcp_server/leases","summary":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","description":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"DHCP leases","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_log","title":"GET /api/v2/status/logs/dhcp","summary":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","description":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 DHCP log lines","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_static_mappings","title":"GET /api/v2/services/dhcp_server/static_mappings","summary":"List the DHCP static mappings on one interface — each mapping's id, MAC, reserved address, hostname, description, and whether it also gets a static ARP entry. This is the read that names the object every static-mapping write acts on: the delete takes the id this returns.","description":"List the DHCP static mappings on one interface — each mapping's id, MAC, reserved address, hostname, description, and whether it also gets a static ARP entry. This is the read that names the object every static-mapping write acts on: the delete takes the id this returns.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface the DHCP server runs on, as pfSense names it (lan, opt1, …).","validation":{"pattern":"^[a-zA-Z0-9_]{1,32}$"}}],"examples":[{"title":"Static mappings on LAN","args":{"interface":"lan"}}],"search_terms":[]},{"id":"pfsense.dns_resolver_settings","title":"GET /api/v2/services/dns_resolver/settings","summary":"Show the DNS Resolver (Unbound) configuration — whether it is enabled, the listen and TLS ports, the interfaces it binds and forwards out of, DNSSEC and forwarding mode, and the DHCP/OpenVPN registration flags. The operator's free-text `custom_options` block is never returned: it is raw Unbound config an operator can put anything in, including forwarding credentials, so the action selects only the settings above and drops it at the source.","description":"Show the DNS Resolver (Unbound) configuration — whether it is enabled, the listen and TLS ports, the interfaces it binds and forwards out of, DNSSEC and forwarding mode, and the DHCP/OpenVPN registration flags. The operator's free-text `custom_options` block is never returned: it is raw Unbound config an operator can put anything in, including forwarding credentials, so the action selects only the settings above and drops it at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Resolver configuration","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_log","title":"GET /api/v2/status/logs/firewall","summary":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","description":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 firewall log lines","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_rules","title":"GET /api/v2/firewall/rules","summary":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","description":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All filter rules","args":{}}],"search_terms":[]},{"id":"pfsense.flush_states","title":"DELETE /api/v2/firewall/states","summary":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","description":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","kind":"script","risk":"high","side_effects":["Clears the entire pf state table.","Every active connection through the firewall is dropped and must reconnect."],"args":[],"examples":[{"title":"Flush the state table","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_groups","title":"GET /api/v2/routing/gateway/groups","summary":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","description":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway groups","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_status","title":"GET /api/v2/status/gateways","summary":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","description":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway health","args":{}}],"search_terms":[]},{"id":"pfsense.gateways","title":"GET /api/v2/routing/gateways","summary":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","description":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured gateways","args":{}}],"search_terms":[]},{"id":"pfsense.interface_config","title":"GET /api/v2/interfaces","summary":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","description":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All interface configuration","args":{}}],"search_terms":[]},{"id":"pfsense.interface_status","title":"GET /api/v2/status/interfaces","summary":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","description":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_child_sas","title":"GET /api/v2/status/ipsec/child_sas","summary":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","description":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec child SAs","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_status","title":"GET /api/v2/status/ipsec/sas","summary":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","description":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec SAs","args":{}}],"search_terms":[]},{"id":"pfsense.nat_outbound","title":"GET /api/v2/firewall/nat/outbound/mappings","summary":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","description":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Outbound NAT","args":{}}],"search_terms":[]},{"id":"pfsense.nat_port_forwards","title":"GET /api/v2/firewall/nat/port_forwards","summary":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","description":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Port forwards","args":{}}],"search_terms":[]},{"id":"pfsense.ntp_settings","title":"GET /api/v2/services/ntp/settings","summary":"Show the NTP service configuration — whether it is enabled, the interfaces it binds, the poll interval bounds, orphan-mode stratum, peer limit, logging and statistics flags, leap-second handling, and whether server authentication is on with which algorithm. The shared authentication key itself is never returned: the action selects only the settings above, so `serverauthkey` is dropped at the source.","description":"Show the NTP service configuration — whether it is enabled, the interfaces it binds, the poll interval bounds, orphan-mode stratum, peer limit, logging and statistics flags, leap-second handling, and whether server authentication is on with which algorithm. The shared authentication key itself is never returned: the action selects only the settings above, so `serverauthkey` is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"NTP configuration","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_log","title":"GET /api/v2/status/logs/openvpn","summary":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","description":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 OpenVPN log lines","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_status","title":"GET /api/v2/status/openvpn/servers","summary":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","description":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"OpenVPN status","args":{}}],"search_terms":[]},{"id":"pfsense.pf_table","title":"GET /api/v2/diagnostics/table","summary":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","description":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"pf table name (from pfsense.pf_tables), e.g. sshguard, bogons, virusprot.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}}],"examples":[{"title":"Addresses sshguard is blocking","args":{"name":"sshguard"}}],"search_terms":[]},{"id":"pfsense.pf_tables","title":"GET /api/v2/diagnostics/tables","summary":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","description":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All pf table names","args":{}}],"search_terms":[]},{"id":"pfsense.reboot","title":"POST /api/v2/diagnostics/reboot","summary":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","description":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","kind":"script","risk":"critical","side_effects":["Reboots the firewall.","All traffic through the firewall stops until the boot completes."],"args":[],"examples":[{"title":"Reboot the firewall","args":{}}],"search_terms":[]},{"id":"pfsense.restart_service","title":"POST /api/v2/status/service (restart)","summary":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","description":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","kind":"script","risk":"high","side_effects":["Restarts the named service.","The service is briefly unavailable; dependent connectivity may drop."],"args":[{"name":"service","type":"string","required":true,"description":"Service name as listed by service_status, e.g. unbound, openvpn, ipsec.","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}$"}}],"examples":[{"title":"Restart the DNS Resolver","args":{"service":"unbound"}}],"search_terms":[]},{"id":"pfsense.service_status","title":"GET /api/v2/status/services","summary":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","description":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Service status","args":{}}],"search_terms":[]},{"id":"pfsense.states_size","title":"GET /api/v2/firewall/states/size","summary":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","description":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"State table count vs max","args":{}}],"search_terms":[]},{"id":"pfsense.static_routes","title":"GET /api/v2/routing/static_routes","summary":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","description":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Static routes","args":{}}],"search_terms":[]},{"id":"pfsense.system_log","title":"GET /api/v2/status/logs/system","summary":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","description":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 system log lines","args":{}}],"search_terms":[]},{"id":"pfsense.system_packages","title":"GET /api/v2/system/packages","summary":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","description":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Installed packages","args":{}}],"search_terms":[]},{"id":"pfsense.system_status","title":"GET /api/v2/status/system","summary":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","description":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"System health","args":{}}],"search_terms":[]},{"id":"pfsense.version","title":"GET /api/v2/system/version","summary":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","description":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[]},{"id":"pfsense.virtual_ips","title":"GET /api/v2/firewall/virtual_ips","summary":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","description":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All virtual IPs","args":{}}],"search_terms":[]},{"id":"pfsense.wireguard_peers","title":"GET /api/v2/vpn/wireguard/peers","summary":"List the configured WireGuard peers — each peer's description, whether it is enabled, the tunnel it belongs to, its endpoint host and port, keepalive interval, public key, and allowed IPs, for answering \"is this peer configured and pointed where I think it is\". The peer's optional pre-shared key is never returned: the action selects only the fields above, so `presharedkey` is dropped at the source.","description":"List the configured WireGuard peers — each peer's description, whether it is enabled, the tunnel it belongs to, its endpoint host and port, keepalive interval, public key, and allowed IPs, for answering \"is this peer configured and pointed where I think it is\". The peer's optional pre-shared key is never returned: the action selects only the fields above, so `presharedkey` is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured peers","args":{}}],"search_terms":[]}]},{"version":"0.4.4","content_hash":"sha256:6783a0af85dbdf31da0b2adb4ce90191e9d8e9d147528320206ebbf7785fb3f6","tarball_url":"https://registry.emisar.dev/v1/packs/pfsense/0.4.4/6783a0af85dbdf31da0b2adb4ce90191e9d8e9d147528320206ebbf7785fb3f6/pack.tar.gz","actions":[{"id":"pfsense.aliases","title":"GET /api/v2/firewall/aliases","summary":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","description":"List firewall aliases (named host / network / port groups) and their members. Use to see which IPs a block/allow list currently contains.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All aliases","args":{}}],"search_terms":[]},{"id":"pfsense.apply_filter","title":"POST /api/v2/firewall/apply","summary":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","description":"Apply staged firewall changes — reloads the pf filter so pending rule, NAT, or alias edits take effect. Idempotent and low blast radius, but it does push whatever is currently staged into the live ruleset.","kind":"script","risk":"medium","side_effects":["Reloads the firewall filter (brief).","Applies any staged firewall configuration changes to the live ruleset."],"args":[],"examples":[{"title":"Apply staged firewall changes","args":{}}],"search_terms":[]},{"id":"pfsense.arp_table","title":"GET /api/v2/diagnostics/arp_table","summary":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","description":"Show the ARP table — IP ↔ MAC ↔ interface, with hostname and expiry. Use to confirm a host is on the network and which interface it is on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"ARP table","args":{}}],"search_terms":[]},{"id":"pfsense.auth_log","title":"GET /api/v2/status/logs/auth","summary":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","description":"Show recent authentication-log entries — webConfigurator and SSH logins to the firewall, successes and failures, with user and source IP. Use to spot brute-force attempts or confirm who logged in.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 auth log lines","args":{}}],"search_terms":[]},{"id":"pfsense.carp_status","title":"GET /api/v2/status/carp","summary":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","description":"Show CARP high-availability status — whether this node is MASTER or BACKUP and the state of each virtual IP. Use to confirm HA roles after a failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"CARP / HA state","args":{}}],"search_terms":[]},{"id":"pfsense.certificate_authorities","title":"GET /api/v2/system/certificate_authorities","summary":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","description":"List the certificate authorities — each CA's description, refid, parent CA (caref, for intermediates), OS-trust-store flag, and serial. The CA private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source. (The REST API exposes no structured expiry for CAs; use pfsense.certificates for cert validity windows.)","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate authorities","args":{}}],"search_terms":[]},{"id":"pfsense.certificates","title":"GET /api/v2/system/certificates","summary":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","description":"List the certificate store — each certificate's description, refid, signing CA (caref), type, and validity window (valid_from / valid_until / valid_days_left) for expiry monitoring. The private key is never returned: the action selects only these non-secret fields, so the `prv` PEM is dropped at the source.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate store with expiry","args":{}}],"search_terms":[]},{"id":"pfsense.config_history","title":"GET /api/v2/diagnostics/config_history/revisions","summary":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","description":"List the saved configuration revisions — the change history with each revision's time, description (what changed), and the user who made it. Use to answer \"what changed on the firewall and when\". Returns revision metadata only, not the full configuration.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configuration change history","args":{}}],"search_terms":[]},{"id":"pfsense.crls","title":"GET /api/v2/system/crls","summary":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","description":"List the certificate revocation lists — each CRL's description, refid, issuing CA (caref), method (internal / existing), lifetime, serial, and the count of revoked certificates. The raw CRL PEM and the full revoked-entry list are omitted to keep the output compact (neither is a secret).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Certificate revocation lists","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_leases","title":"GET /api/v2/status/dhcp_server/leases","summary":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","description":"List DHCP leases — IP, MAC, hostname, and state (active / expired / static). Works for both the ISC and Kea backends. Use to find what a device was assigned.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"DHCP leases","args":{}}],"search_terms":[]},{"id":"pfsense.dhcp_log","title":"GET /api/v2/status/logs/dhcp","summary":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","description":"Show recent DHCP server log entries — lease discover/offer/request/ack and declines, with client MACs and assigned addresses. Use to debug a client that is not getting an address or to see who leased what.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 DHCP log lines","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_log","title":"GET /api/v2/status/logs/firewall","summary":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","description":"Show recent firewall filter-log entries — blocked/passed packets with time, interface, action, and source/destination. Use to see what is being dropped.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 firewall log lines","args":{}}],"search_terms":[]},{"id":"pfsense.firewall_rules","title":"GET /api/v2/firewall/rules","summary":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","description":"List all configured firewall filter rules, in order, with interface, action, source, destination, and description. Use to see what is allowed or blocked.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All filter rules","args":{}}],"search_terms":[]},{"id":"pfsense.flush_states","title":"DELETE /api/v2/firewall/states","summary":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","description":"Flush the entire firewall state table — drops every tracked connection through the firewall. Existing sessions must re-establish. Use to clear a stuck state table or force traffic to re-evaluate against new rules.","kind":"script","risk":"high","side_effects":["Clears the entire pf state table.","Every active connection through the firewall is dropped and must reconnect."],"args":[],"examples":[{"title":"Flush the state table","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_groups","title":"GET /api/v2/routing/gateway/groups","summary":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","description":"List the configured gateway groups — the multi-WAN failover / load-balance tiers that decide which gateway carries traffic when one is down. Use to understand failover policy; pair with gateway_status for live up/down state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway groups","args":{}}],"search_terms":[]},{"id":"pfsense.gateway_status","title":"GET /api/v2/status/gateways","summary":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","description":"Show gateway monitoring (dpinger) — per-gateway up/down state, RTT, std-dev, and packet loss. Use to diagnose WAN / multi-WAN failover.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Gateway health","args":{}}],"search_terms":[]},{"id":"pfsense.gateways","title":"GET /api/v2/routing/gateways","summary":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","description":"List the configured gateways (the routing config, not live status) — each gateway's name, interface, gateway/monitor IP, default flag, and weight. Use pfsense.gateway_status for live dpinger up/down/RTT, and pfsense.gateway_groups for failover groups.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Configured gateways","args":{}}],"search_terms":[]},{"id":"pfsense.interface_config","title":"GET /api/v2/interfaces","summary":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","description":"List the configured network interfaces — assignment, description, IPv4/IPv6 addressing mode, and MTU. This is the configuration; use interface_status for live link state and counters.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All interface configuration","args":{}}],"search_terms":[]},{"id":"pfsense.interface_status","title":"GET /api/v2/status/interfaces","summary":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","description":"Show per-interface live status — link state, IPv4/IPv6 addresses, media, and in/out packet + byte + error counters. Use to spot a down WAN or errors.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Interface status","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_child_sas","title":"GET /api/v2/status/ipsec/child_sas","summary":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","description":"Show IPsec child SAs (phase 2) — the installed traffic-selector pairs that actually carry tunnel traffic, with state, bytes, and lifetime. Pair with ipsec_status (phase-1 IKE SAs) to tell \"tunnel up\" from \"tunnel passing traffic\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec child SAs","args":{}}],"search_terms":[]},{"id":"pfsense.ipsec_status","title":"GET /api/v2/status/ipsec/sas","summary":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","description":"Show IPsec security associations — phase-1 IKE SAs and their state (established or not), peers, and algorithms. Use to check whether a site-to-site tunnel is up.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"IPsec SAs","args":{}}],"search_terms":[]},{"id":"pfsense.nat_outbound","title":"GET /api/v2/firewall/nat/outbound/mappings","summary":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","description":"List outbound NAT mappings — how internal traffic is translated leaving the firewall. Use to debug source-NAT and masquerade behaviour.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Outbound NAT","args":{}}],"search_terms":[]},{"id":"pfsense.nat_port_forwards","title":"GET /api/v2/firewall/nat/port_forwards","summary":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","description":"List inbound NAT port-forward rules — external port/interface to internal target. Use to audit what is exposed.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Port forwards","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_log","title":"GET /api/v2/status/logs/openvpn","summary":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","description":"Show recent OpenVPN log entries — tunnel up/down, client connect/disconnect, and TLS/auth handshake errors. Use to debug VPN connectivity or a client that cannot establish a tunnel. See pfsense.openvpn_status for live session state.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 OpenVPN log lines","args":{}}],"search_terms":[]},{"id":"pfsense.openvpn_status","title":"GET /api/v2/status/openvpn/servers","summary":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","description":"Show OpenVPN server status — each server and its connected clients (common name, real address, bytes in/out, connected-since). Use to see who is on the VPN.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"OpenVPN status","args":{}}],"search_terms":[]},{"id":"pfsense.pf_table","title":"GET /api/v2/diagnostics/table","summary":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","description":"Show the addresses in one pf table by name (list the names with pfsense.pf_tables) — e.g. which IPs sshguard or a pfBlocker alias is currently blocking. pfBlocker feed tables can hold tens of thousands of entries, so the output is deliberately capped and returned as text; a table larger than the cap is truncated — narrow to a specific smaller table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"pf table name (from pfsense.pf_tables), e.g. sshguard, bogons, virusprot.","validation":{"pattern":"^[a-zA-Z0-9_\\-]{1,64}$"}}],"examples":[{"title":"Addresses sshguard is blocking","args":{"name":"sshguard"}}],"search_terms":[]},{"id":"pfsense.pf_tables","title":"GET /api/v2/diagnostics/tables","summary":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","description":"List the pf table NAMES defined on the firewall (bogons, sshguard, virusprot, pfBlocker aliases, …) — just the names, not their contents. Use pfsense.pf_table to read the addresses in one table (some tables hold tens of thousands of entries).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All pf table names","args":{}}],"search_terms":[]},{"id":"pfsense.reboot","title":"POST /api/v2/diagnostics/reboot","summary":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","description":"Reboot the firewall. All traffic through the box stops until it finishes booting, and there is no remote undo. Use only when a reboot is genuinely required.","kind":"script","risk":"critical","side_effects":["Reboots the firewall.","All traffic through the firewall stops until the boot completes."],"args":[],"examples":[{"title":"Reboot the firewall","args":{}}],"search_terms":[]},{"id":"pfsense.restart_service","title":"POST /api/v2/status/service (restart)","summary":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","description":"Restart a pfSense service by name (unbound, dhcpd, openvpn, ipsec, dpinger, …). The service is briefly unavailable while it restarts, so dependent connectivity can blip.","kind":"script","risk":"high","side_effects":["Restarts the named service.","The service is briefly unavailable; dependent connectivity may drop."],"args":[{"name":"service","type":"string","required":true,"description":"Service name as listed by service_status, e.g. unbound, openvpn, ipsec.","validation":{"pattern":"^[a-zA-Z0-9_]{1,64}$"}}],"examples":[{"title":"Restart the DNS Resolver","args":{"service":"unbound"}}],"search_terms":[]},{"id":"pfsense.service_status","title":"GET /api/v2/status/services","summary":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","description":"List all pfSense services with their enabled flag and running state (unbound, dhcpd/kea, openvpn, ipsec, dpinger, …). Use to find a stopped service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Service status","args":{}}],"search_terms":[]},{"id":"pfsense.states_size","title":"GET /api/v2/firewall/states/size","summary":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","description":"Show current firewall state-table count and the configured maximum. Use to watch for state exhaustion. Cheap — does not dump the whole table.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"State table count vs max","args":{}}],"search_terms":[]},{"id":"pfsense.static_routes","title":"GET /api/v2/routing/static_routes","summary":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","description":"List configured static routes — destination network, gateway, and description. Use to check routing for a reachability problem.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Static routes","args":{}}],"search_terms":[]},{"id":"pfsense.system_log","title":"GET /api/v2/status/logs/system","summary":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","description":"Show recent system-log entries — the general pfSense log (boot, services, errors). Use for \"what happened on the box recently?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log lines to return.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 system log lines","args":{}}],"search_terms":[]},{"id":"pfsense.system_packages","title":"GET /api/v2/system/packages","summary":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","description":"List the installed pfSense add-on packages with their installed version and whether an update is available. Use to confirm what is loaded on the box (e.g. the FRR or REST API package) and what is out of date.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Installed packages","args":{}}],"search_terms":[]},{"id":"pfsense.system_status","title":"GET /api/v2/status/system","summary":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","description":"Show firewall system health — version, uptime, CPU model/usage/load, memory, swap, mbuf and disk usage, and temperature. The first stop for \"how is the box doing?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"System health","args":{}}],"search_terms":[]},{"id":"pfsense.version","title":"GET /api/v2/system/version","summary":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","description":"Show pfSense version, build, and kernel. Cheap connectivity + auth check, and the pack's verify action.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[]},{"id":"pfsense.virtual_ips","title":"GET /api/v2/firewall/virtual_ips","summary":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","description":"List the configured virtual IPs (VIPs) — CARP, IP-alias, and proxy-ARP — with interface, subnet, type, and CARP vhid. Use to audit the shared HA addresses; pair with carp_status for which node currently owns each.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the pfSense REST API.","Read-only."],"args":[],"examples":[{"title":"All virtual IPs","args":{}}],"search_terms":[]}]}]},{"id":"php-fpm","name":"PHP-FPM","version":"0.1.13","description":"PHP runtime + FPM pool introspection — version, modules, ini, pool status (via fpm_status endpoint), error + slow logs, OPcache state, Composer manifest. Read-only. Set PHP_FPM_STATUS_URL env to point to the FPM status endpoint.","vendor":"emisar","homepage":"https://emisar.dev/packs/php-fpm","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/php-fpm","content_hash":"sha256:089d53161ed6b637e2a76286a29a6366256a6bcceed11e74593d15bec7a520d8","tarball_url":"https://registry.emisar.dev/v1/packs/php-fpm/0.1.13/089d53161ed6b637e2a76286a29a6366256a6bcceed11e74593d15bec7a520d8/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":["php-fpm"],"ports":[]},"setup":{"summary":"Inspects the local PHP runtime and FPM pool on the runner host (php -v / --ini, logs, OPcache, Composer) — no credentials needed.","env":[{"name":"PHP_FPM_STATUS_URL","description":"URL of the FPM pool status page, used by the fpm_status/fpm_status_full/fpm_ping actions. Optional; defaults to http://127.0.0.1/fpm-status. Add it to the runner's `inherit_env` if you override it.","default":"http://127.0.0.1/fpm-status"},{"name":"PHP_FPM_ERROR_LOG","description":"Path to the PHP-FPM error log. Add it to the runner's `inherit_env` if you override it.","default":"/var/log/php-fpm/error.log"},{"name":"PHP_FPM_SLOW_LOG","description":"Path to the PHP-FPM slow-request log. Add it to the runner's `inherit_env` if you override it.","default":"/var/log/php-fpm/slow.log"},{"name":"COMPOSER_DIR","description":"Composer project directory inspected by composer_show. Add it to the runner's `inherit_env` if you override it.","default":"/var/www/html"}],"notes":["The status page must be enabled in the pool config (pm.status_path) and reachable from the runner host for the fpm_status actions to return data.","Debian/Ubuntu log paths vary by installed PHP version. Set and allowlist `PHP_FPM_ERROR_LOG` and `PHP_FPM_SLOW_LOG`, then grant persistent read access through that deployment's log group or rotation policy."],"host_access":[{"actions":["phpfpm.error_log_tail","phpfpm.slow_log_tail","phpfpm.composer_show"],"requirement":"Read PHP-FPM's root-owned logs and the deployment-owned Composer project.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-php-fpm-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root","sudo test -r /var/log/php-fpm/error.log","sudo test -r /var/log/php-fpm/slow.log","sudo test -r /var/www/html/composer.lock"],"impact":"Every Emisar action on this runner executes as root. PHP-FPM logs can contain request details and stack traces, while the application tree can contain source and secrets."}]}],"verify":"phpfpm.version"},"actions":[{"id":"phpfpm.composer_show","title":"composer show (in $COMPOSER_DIR)","summary":"List installed Composer packages with versions.","description":"List installed Composer packages with versions.","kind":"exec","risk":"low","side_effects":["Reads composer.lock + vendor/.","Read-only."],"args":[],"examples":[{"title":"Composer packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"${COMPOSER_DIR:-/var/www/html}\" && composer show --format=json --no-interaction 2>/dev/null"]}},{"id":"phpfpm.error_log_tail","title":"tail FPM error_log","summary":"Tail the FPM error log (last N lines).","description":"Tail the FPM error log (last N lines).","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_ERROR_LOG:-/var/log/php-fpm/error.log}\""]}},{"id":"phpfpm.fpm_ping","title":"GET /ping (FPM)","summary":"Check FPM ping endpoint (returns 'pong' if responsive).","description":"Check FPM ping endpoint (returns 'pong' if responsive).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Ping","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PHP_FPM_PING_URL:-http://127.0.0.1/fpm-ping}\""]}},{"id":"phpfpm.fpm_status","title":"GET /status (FPM)","summary":"Show FPM pool summary — active processes, idle, max children, listen queue.","description":"Show FPM pool summary — active processes, idle, max children, listen queue.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Pool status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}\""]}},{"id":"phpfpm.fpm_status_full","title":"GET /status?full (FPM per-process)","summary":"Show per-process detail: pid, state, last request URI, current memory peak.","description":"Show per-process detail: pid, state, last request URI, current memory peak.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Per-process","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}?full\""]}},{"id":"phpfpm.ini","title":"php --ini","summary":"List all loaded php.ini paths + their contents path.","description":"List all loaded php.ini paths + their contents path.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"ini files","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["--ini"]}},{"id":"phpfpm.modules","title":"php -m","summary":"List all loaded extensions.","description":"List all loaded extensions.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-m"]}},{"id":"phpfpm.opcache_status","title":"GET /opcache-status","summary":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","description":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"OPcache","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PHP_OPCACHE_URL:-http://127.0.0.1/opcache-status.php}\""]}},{"id":"phpfpm.slow_log_tail","title":"tail FPM slow_log","summary":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","description":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":500,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Slow trace","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_SLOW_LOG:-/var/log/php-fpm/slow.log}\""]}},{"id":"phpfpm.version","title":"php -v","summary":"Show PHP version + SAPI + Zend Engine version.","description":"Show PHP version + SAPI + Zend Engine version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-v"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:6e75dd1561b61d5ad1e90684897d4d0a02be60ce79713150a94cf3253210402e","tarball_url":"https://registry.emisar.dev/v1/packs/php-fpm/0.1.9/6e75dd1561b61d5ad1e90684897d4d0a02be60ce79713150a94cf3253210402e/pack.tar.gz","actions":[{"id":"phpfpm.composer_show","title":"composer show (in $COMPOSER_DIR)","summary":"List installed Composer packages with versions.","description":"List installed Composer packages with versions.","kind":"exec","risk":"low","side_effects":["Reads composer.lock + vendor/.","Read-only."],"args":[],"examples":[{"title":"Composer packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"${COMPOSER_DIR:-/var/www/html}\" && composer show --format=json --no-interaction 2>/dev/null"]}},{"id":"phpfpm.error_log_tail","title":"tail FPM error_log","summary":"Tail the FPM error log (last N lines).","description":"Tail the FPM error log (last N lines).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_ERROR_LOG:-/var/log/php-fpm/error.log}\""]}},{"id":"phpfpm.fpm_ping","title":"GET /ping (FPM)","summary":"Check FPM ping endpoint (returns 'pong' if responsive).","description":"Check FPM ping endpoint (returns 'pong' if responsive).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Ping","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_FPM_PING_URL:-http://127.0.0.1/fpm-ping}\""]}},{"id":"phpfpm.fpm_status","title":"GET /status (FPM)","summary":"Show FPM pool summary — active processes, idle, max children, listen queue.","description":"Show FPM pool summary — active processes, idle, max children, listen queue.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Pool status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}\""]}},{"id":"phpfpm.fpm_status_full","title":"GET /status?full (FPM per-process)","summary":"Show per-process detail: pid, state, last request URI, current memory peak.","description":"Show per-process detail: pid, state, last request URI, current memory peak.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Per-process","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}?full\""]}},{"id":"phpfpm.ini","title":"php --ini","summary":"List all loaded php.ini paths + their contents path.","description":"List all loaded php.ini paths + their contents path.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"ini files","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["--ini"]}},{"id":"phpfpm.modules","title":"php -m","summary":"List all loaded extensions.","description":"List all loaded extensions.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-m"]}},{"id":"phpfpm.opcache_status","title":"GET /opcache-status","summary":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","description":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"OPcache","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_OPCACHE_URL:-http://127.0.0.1/opcache-status.php}\""]}},{"id":"phpfpm.slow_log_tail","title":"tail FPM slow_log","summary":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","description":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":500,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Slow trace","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_SLOW_LOG:-/var/log/php-fpm/slow.log}\""]}},{"id":"phpfpm.version","title":"php -v","summary":"Show PHP version + SAPI + Zend Engine version.","description":"Show PHP version + SAPI + Zend Engine version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-v"]}}]},{"version":"0.1.7","content_hash":"sha256:ef44b8e073de7f2062006e1dd546c789d9cc17dd151dad0090be3a53ba13fa47","tarball_url":"https://registry.emisar.dev/v1/packs/php-fpm/0.1.7/ef44b8e073de7f2062006e1dd546c789d9cc17dd151dad0090be3a53ba13fa47/pack.tar.gz","actions":[{"id":"phpfpm.composer_show","title":"composer show (in $COMPOSER_DIR)","summary":"List installed Composer packages with versions.","description":"List installed Composer packages with versions.","kind":"exec","risk":"low","side_effects":["Reads composer.lock + vendor/.","Read-only."],"args":[],"examples":[{"title":"Composer packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"${COMPOSER_DIR:-/var/www/html}\" && composer show --format=json --no-interaction 2>/dev/null"]}},{"id":"phpfpm.error_log_tail","title":"tail FPM error_log","summary":"Tail the FPM error log (last N lines).","description":"Tail the FPM error log (last N lines).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_ERROR_LOG:-/var/log/php-fpm/error.log}\""]}},{"id":"phpfpm.fpm_ping","title":"GET /ping (FPM)","summary":"Check FPM ping endpoint (returns 'pong' if responsive).","description":"Check FPM ping endpoint (returns 'pong' if responsive).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Ping","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_FPM_PING_URL:-http://127.0.0.1/fpm-ping}\""]}},{"id":"phpfpm.fpm_status","title":"GET /status (FPM)","summary":"Show FPM pool summary — active processes, idle, max children, listen queue.","description":"Show FPM pool summary — active processes, idle, max children, listen queue.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Pool status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}\""]}},{"id":"phpfpm.fpm_status_full","title":"GET /status?full (FPM per-process)","summary":"Show per-process detail: pid, state, last request URI, current memory peak.","description":"Show per-process detail: pid, state, last request URI, current memory peak.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Per-process","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}?full\""]}},{"id":"phpfpm.ini","title":"php --ini","summary":"List all loaded php.ini paths + their contents path.","description":"List all loaded php.ini paths + their contents path.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"ini files","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["--ini"]}},{"id":"phpfpm.modules","title":"php -m","summary":"List all loaded extensions.","description":"List all loaded extensions.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-m"]}},{"id":"phpfpm.opcache_status","title":"GET /opcache-status","summary":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","description":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"OPcache","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PHP_OPCACHE_URL:-http://127.0.0.1/opcache-status.php}\""]}},{"id":"phpfpm.slow_log_tail","title":"tail FPM slow_log","summary":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","description":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":500,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Slow trace","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_SLOW_LOG:-/var/log/php-fpm/slow.log}\""]}},{"id":"phpfpm.version","title":"php -v","summary":"Show PHP version + SAPI + Zend Engine version.","description":"Show PHP version + SAPI + Zend Engine version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-v"]}}]},{"version":"0.1.6","content_hash":"sha256:cdb84dc070b5ec61c722c77fd91a2494a1d36cfe2a5f0f34bb57ae48f449914f","tarball_url":"https://registry.emisar.dev/v1/packs/php-fpm/0.1.6/cdb84dc070b5ec61c722c77fd91a2494a1d36cfe2a5f0f34bb57ae48f449914f/pack.tar.gz","actions":[{"id":"phpfpm.composer_show","title":"composer show (in $COMPOSER_DIR)","summary":"List installed Composer packages with versions.","description":"List installed Composer packages with versions.","kind":"exec","risk":"low","side_effects":["Reads composer.lock + vendor/.","Read-only."],"args":[],"examples":[{"title":"Composer packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"${COMPOSER_DIR:-/var/www/html}\" && composer show --format=json --no-interaction 2>/dev/null"]}},{"id":"phpfpm.error_log_tail","title":"tail FPM error_log","summary":"Tail the FPM error log (last N lines).","description":"Tail the FPM error log (last N lines).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200 errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_ERROR_LOG:-/var/log/php-fpm/error.log}\""]}},{"id":"phpfpm.fpm_ping","title":"GET /ping (FPM)","summary":"Check FPM ping endpoint (returns 'pong' if responsive).","description":"Check FPM ping endpoint (returns 'pong' if responsive).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Ping","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS \"${PHP_FPM_PING_URL:-http://127.0.0.1/fpm-ping}\""]}},{"id":"phpfpm.fpm_status","title":"GET /status (FPM)","summary":"Show FPM pool summary — active processes, idle, max children, listen queue.","description":"Show FPM pool summary — active processes, idle, max children, listen queue.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Pool status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}\""]}},{"id":"phpfpm.fpm_status_full","title":"GET /status?full (FPM per-process)","summary":"Show per-process detail: pid, state, last request URI, current memory peak.","description":"Show per-process detail: pid, state, last request URI, current memory peak.","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"Per-process","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS \"${PHP_FPM_STATUS_URL:-http://127.0.0.1/fpm-status}?full\""]}},{"id":"phpfpm.ini","title":"php --ini","summary":"List all loaded php.ini paths + their contents path.","description":"List all loaded php.ini paths + their contents path.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"ini files","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["--ini"]}},{"id":"phpfpm.modules","title":"php -m","summary":"List all loaded extensions.","description":"List all loaded extensions.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Modules","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-m"]}},{"id":"phpfpm.opcache_status","title":"GET /opcache-status","summary":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","description":"Show OPcache stats (requires the standard opcache_status.php script reachable at PHP_OPCACHE_URL).","kind":"exec","risk":"low","side_effects":["One HTTP GET.","Read-only."],"args":[],"examples":[{"title":"OPcache","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS \"${PHP_OPCACHE_URL:-http://127.0.0.1/opcache-status.php}\""]}},{"id":"phpfpm.slow_log_tail","title":"tail FPM slow_log","summary":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","description":"Tail the FPM slow log (last N lines of PHP backtraces for slow requests).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":500,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Slow trace","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} \"${PHP_FPM_SLOW_LOG:-/var/log/php-fpm/slow.log}\""]}},{"id":"phpfpm.version","title":"php -v","summary":"Show PHP version + SAPI + Zend Engine version.","description":"Show PHP version + SAPI + Zend Engine version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"php","argv":["-v"]}}]}]},{"id":"podman","name":"Podman containers","version":"0.1.11","description":"Read-only inventory + per-container introspection plus narrow mutators (restart, stop, kill, prune). Drop-in alternative for Docker on RHEL / Fedora hosts. Rootless mode supported as long as the runner uid matches the user that owns the containers.","vendor":"emisar","homepage":"https://emisar.dev/packs/podman","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/podman","content_hash":"sha256:22e3370c6b881f7715d6e4b612e09fb0ba0beb92e1122b6ee3eec8c896ce2387","tarball_url":"https://registry.emisar.dev/v1/packs/podman/0.1.11/22e3370c6b881f7715d6e4b612e09fb0ba0beb92e1122b6ee3eec8c896ce2387/pack.tar.gz","requires":{"os":["linux"],"binaries":["podman"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Drives the local podman CLI on the runner host — no credentials needed.","notes":["Rootless containers require a dedicated runner installed as their owner. The setup recipe cannot name that deployment-specific identity safely."],"host_access":[{"actions":["podman.info","podman.ps","podman.inspect","podman.logs","podman.stats","podman.images","podman.system_df","podman.restart","podman.stop","podman.kill","podman.system_prune"],"requirement":"Reach rootful or system-wide Podman containers as root.","recipes":[{"name":"Run the Emisar service as root for rootful Podman","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-podman-root.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root","sudo podman info >/dev/null"],"impact":"Every Emisar action on this runner executes as root and can read or change all rootful containers and the host resources they can mount."}]}],"verify":"podman.ps"},"actions":[{"id":"podman.images","title":"podman images","summary":"List all local images.","description":"List all local images.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"All images","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["images","--format","json"]}},{"id":"podman.info","title":"podman info","summary":"Show system + storage + network info.","description":"Show system + storage + network info.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"System info","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["info","--format","json"]}},{"id":"podman.inspect","title":"podman inspect <id>","summary":"Show full container details for one ID/name — state, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (values passed with -e), so this is approval-gated; the runner's redaction is a pattern-bound backstop, not a guarantee. Read-only.","description":"Show full container details for one ID/name — state, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (values passed with -e), so this is approval-gated; the runner's redaction is a pattern-bound backstop, not a guarantee. Read-only.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"One container","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["inspect","{{ args.container }}"]}},{"id":"podman.kill","title":"podman kill <id>","summary":"Send SIGKILL: instant termination. In-flight requests are dropped.","description":"Send SIGKILL: instant termination. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGKILL — no graceful shutdown.","In-flight requests lost."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Hard kill","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["kill","{{ args.container }}"]}},{"id":"podman.logs","title":"podman logs <id> --tail <N>","summary":"Tail container logs (last N lines).","description":"Tail container logs (last N lines).","kind":"exec","risk":"medium","side_effects":["One CLI call.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["logs","--tail","{{ args.tail }}","{{ args.container }}"]}},{"id":"podman.ps","title":"podman ps -a","summary":"List all containers (running + stopped).","description":"List all containers (running + stopped).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["ps","-a","--format","json"]}},{"id":"podman.restart","title":"podman restart <id>","summary":"Restart one container. Drops in-flight requests.","description":"Restart one container. Drops in-flight requests.","kind":"exec","risk":"high","side_effects":["Container is stopped (SIGTERM, then SIGKILL) then started.","In-flight connections drop."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart one","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["restart","{{ args.container }}"]}},{"id":"podman.stats","title":"podman stats --no-stream","summary":"Show one-shot CPU/mem/net/io stats for all containers.","description":"Show one-shot CPU/mem/net/io stats for all containers.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Stats snapshot","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["stats","--no-stream","--format","json"]}},{"id":"podman.stop","title":"podman stop <id>","summary":"SIGTERM then SIGKILL after timeout.","description":"SIGTERM then SIGKILL after timeout.","kind":"exec","risk":"high","side_effects":["Container stops.","Restart policy may bring it back unless --rm."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Stop one","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["stop","{{ args.container }}"]}},{"id":"podman.system_df","title":"podman system df","summary":"Show disk usage by images / containers / volumes.","description":"Show disk usage by images / containers / volumes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["system","df"]}},{"id":"podman.system_prune","title":"podman system prune -f","summary":"Remove stopped containers, dangling images, unused networks.","description":"Remove stopped containers, dangling images, unused networks.","kind":"exec","risk":"high","side_effects":["Stopped containers are deleted permanently.","Dangling images + unused networks removed."],"args":[],"examples":[{"title":"Prune","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["system","prune","-f"]}},{"id":"podman.version","title":"podman version","summary":"Show Podman binary + API + runtime versions.","description":"Show Podman binary + API + runtime versions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["version","--format","json"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:ce6001f40ddecf50f77772af34ec55cffdb44ebf6611d1101c49846e2d594ad5","tarball_url":"https://registry.emisar.dev/v1/packs/podman/0.1.9/ce6001f40ddecf50f77772af34ec55cffdb44ebf6611d1101c49846e2d594ad5/pack.tar.gz","actions":[{"id":"podman.images","title":"podman images","summary":"List all local images.","description":"List all local images.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"All images","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["images","--format","json"]}},{"id":"podman.info","title":"podman info","summary":"Show system + storage + network info.","description":"Show system + storage + network info.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"System info","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["info","--format","json"]}},{"id":"podman.inspect","title":"podman inspect <id>","summary":"Show full container details for one ID/name — state, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (values passed with -e), so this is approval-gated; the runner's redaction is a pattern-bound backstop, not a guarantee. Read-only.","description":"Show full container details for one ID/name — state, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (values passed with -e), so this is approval-gated; the runner's redaction is a pattern-bound backstop, not a guarantee. Read-only.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"One container","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["inspect","{{ args.container }}"]}},{"id":"podman.kill","title":"podman kill <id>","summary":"Send SIGKILL: instant termination. In-flight requests are dropped.","description":"Send SIGKILL: instant termination. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGKILL — no graceful shutdown.","In-flight requests lost."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Hard kill","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["kill","{{ args.container }}"]}},{"id":"podman.logs","title":"podman logs <id> --tail <N>","summary":"Tail container logs (last N lines).","description":"Tail container logs (last N lines).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["logs","--tail","{{ args.tail }}","{{ args.container }}"]}},{"id":"podman.ps","title":"podman ps -a","summary":"List all containers (running + stopped).","description":"List all containers (running + stopped).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["ps","-a","--format","json"]}},{"id":"podman.restart","title":"podman restart <id>","summary":"Restart one container. Drops in-flight requests.","description":"Restart one container. Drops in-flight requests.","kind":"exec","risk":"high","side_effects":["Container is stopped (SIGTERM, then SIGKILL) then started.","In-flight connections drop."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart one","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["restart","{{ args.container }}"]}},{"id":"podman.stats","title":"podman stats --no-stream","summary":"Show one-shot CPU/mem/net/io stats for all containers.","description":"Show one-shot CPU/mem/net/io stats for all containers.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Stats snapshot","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["stats","--no-stream","--format","json"]}},{"id":"podman.stop","title":"podman stop <id>","summary":"SIGTERM then SIGKILL after timeout.","description":"SIGTERM then SIGKILL after timeout.","kind":"exec","risk":"high","side_effects":["Container stops.","Restart policy may bring it back unless --rm."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Stop one","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["stop","{{ args.container }}"]}},{"id":"podman.system_df","title":"podman system df","summary":"Show disk usage by images / containers / volumes.","description":"Show disk usage by images / containers / volumes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["system","df"]}},{"id":"podman.system_prune","title":"podman system prune -f","summary":"Remove stopped containers, dangling images, unused networks.","description":"Remove stopped containers, dangling images, unused networks.","kind":"exec","risk":"high","side_effects":["Stopped containers are deleted permanently.","Dangling images + unused networks removed."],"args":[],"examples":[{"title":"Prune","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["system","prune","-f"]}},{"id":"podman.version","title":"podman version","summary":"Show Podman binary + API + runtime versions.","description":"Show Podman binary + API + runtime versions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["version","--format","json"]}}]},{"version":"0.1.8","content_hash":"sha256:3dfea05b8ebd5f4230d2be5487917045bc85d3f94b1e5643aaa2acd531d03eb5","tarball_url":"https://registry.emisar.dev/v1/packs/podman/0.1.8/3dfea05b8ebd5f4230d2be5487917045bc85d3f94b1e5643aaa2acd531d03eb5/pack.tar.gz","actions":[{"id":"podman.images","title":"podman images","summary":"List all local images.","description":"List all local images.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"All images","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["images","--format","json"]}},{"id":"podman.info","title":"podman info","summary":"Show system + storage + network info.","description":"Show system + storage + network info.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"System info","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["info","--format","json"]}},{"id":"podman.inspect","title":"podman inspect <id>","summary":"Show full container details for one ID/name — state, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (values passed with -e), so this is approval-gated; the runner's redaction is a pattern-bound backstop, not a guarantee. Read-only.","description":"Show full container details for one ID/name — state, mounts, network config, labels, and the container's env. The env commonly carries injected secrets (values passed with -e), so this is approval-gated; the runner's redaction is a pattern-bound backstop, not a guarantee. Read-only.","kind":"exec","risk":"high","side_effects":["One CLI call.","Read-only, but exposes the container's env (may include secrets)."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"One container","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["inspect","{{ args.container }}"]}},{"id":"podman.kill","title":"podman kill <id>","summary":"Send SIGKILL: instant termination. In-flight requests are dropped.","description":"Send SIGKILL: instant termination. In-flight requests are dropped.","kind":"exec","risk":"high","side_effects":["SIGKILL — no graceful shutdown.","In-flight requests lost."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Hard kill","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["kill","{{ args.container }}"]}},{"id":"podman.logs","title":"podman logs <id> --tail <N>","summary":"Tail container logs (last N lines).","description":"Tail container logs (last N lines).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}},{"name":"tail","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["logs","--tail","{{ args.tail }}","{{ args.container }}"]}},{"id":"podman.ps","title":"podman ps -a","summary":"List all containers (running + stopped).","description":"List all containers (running + stopped).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["ps","-a","--format","json"]}},{"id":"podman.restart","title":"podman restart <id>","summary":"Restart one container. Drops in-flight requests.","description":"Restart one container. Drops in-flight requests.","kind":"exec","risk":"high","side_effects":["Container is stopped (SIGTERM, then SIGKILL) then started.","In-flight connections drop."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Restart one","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["restart","{{ args.container }}"]}},{"id":"podman.stats","title":"podman stats --no-stream","summary":"Show one-shot CPU/mem/net/io stats for all containers.","description":"Show one-shot CPU/mem/net/io stats for all containers.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Stats snapshot","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["stats","--no-stream","--format","json"]}},{"id":"podman.stop","title":"podman stop <id>","summary":"SIGTERM then SIGKILL after timeout.","description":"SIGTERM then SIGKILL after timeout.","kind":"exec","risk":"high","side_effects":["Container stops.","Restart policy may bring it back unless --rm."],"args":[{"name":"container","type":"string","required":true,"description":"Container ID or name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Stop one","args":{"container":"web"}}],"search_terms":[],"command":{"binary":"podman","argv":["stop","{{ args.container }}"]}},{"id":"podman.system_df","title":"podman system df","summary":"Show disk usage by images / containers / volumes.","description":"Show disk usage by images / containers / volumes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Disk usage","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["system","df"]}},{"id":"podman.system_prune","title":"podman system prune -f","summary":"Remove stopped containers, dangling images, unused networks.","description":"Remove stopped containers, dangling images, unused networks.","kind":"exec","risk":"high","side_effects":["Stopped containers are deleted permanently.","Dangling images + unused networks removed."],"args":[],"examples":[{"title":"Prune","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["system","prune","-f"]}},{"id":"podman.version","title":"podman version","summary":"Show Podman binary + API + runtime versions.","description":"Show Podman binary + API + runtime versions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"podman","argv":["version","--format","json"]}}]}],"retired_below":"0.1.8"},{"id":"postfix","name":"Postfix mail server","version":"0.1.17","description":"Queue inspection, config dump, log tailing, plus narrow operator actions (flush, requeue, delete-by-queue-id). These mutators are high- or critical-risk; the reversible hold/release pause is medium. All are audited. Queue inspection and mutation run as root because the runner's no-new-privileges boundary prevents Postfix helpers from elevating.","vendor":"emisar","homepage":"https://emisar.dev/packs/postfix","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/postfix","content_hash":"sha256:ecda601e204b4193f8405563b7e9aebd8c26e19ecbdf2a5ee0d79fe12a334e0c","tarball_url":"https://registry.emisar.dev/v1/packs/postfix/0.1.17/ecda601e204b4193f8405563b7e9aebd8c26e19ecbdf2a5ee0d79fe12a334e0c/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":["postqueue"],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local Postfix instance on the runner host — no credentials needed. Uses the standard binaries (postqueue, postconf, mailq, postsuper) and reads the queue under `/var/spool/postfix`.","notes":["maillog actions read `/var/log/mail.log`, falling back to `/var/log/maillog` (RHEL-family)."],"host_access":[{"actions":["postfix.mailq","postfix.qshape","postfix.queue_counts","postfix.postcat_qid","postfix.flush_queue","postfix.delete_qid","postfix.check_config","postfix.reload","postfix.postsuper_hold","postfix.postsuper_release","postfix.postsuper_requeue"],"requirement":"Read protected queue files and mail logs, or validate and mutate Postfix state, as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-postfix-root.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. Postfix actions can remove, inspect, flush, requeue, hold, or release messages and reload the mail service."}]},{"actions":["postfix.maillog_tail","postfix.maillog_grep"],"requirement":"Read Postfix logs through the Debian or Ubuntu system log-reader group.","recipes":[{"name":"Add the default Emisar service user to adm","commands":["sudo usermod -aG adm emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx adm","sudo -u emisar test -r /var/log/mail.log"],"impact":"Every process running as emisar can read every host log granted to adm, not only Postfix logs. RHEL-family paths need an equivalent persistent log-reader grant."}]}],"verify":"postfix.mailq"},"actions":[{"id":"postfix.check_config","title":"postfix check","summary":"Validate Postfix configuration files.","description":"Validate Postfix configuration files.","kind":"exec","risk":"low","side_effects":["Reads main.cf + master.cf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["check"]}},{"id":"postfix.delete_qid","title":"postsuper -d <queue-id>","summary":"Delete one queued message. Permanent — message is lost.","description":"Delete one queued message. Permanent — message is lost.","kind":"exec","risk":"critical","side_effects":["Message is removed from the queue.","Sender is NOT notified."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Drop one stuck message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-d","{{ args.queue_id }}"]}},{"id":"postfix.flush_queue","title":"postqueue -f (retry all deferred)","summary":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","description":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","kind":"exec","risk":"high","side_effects":["Every deferred message is re-attempted immediately.","Downstream MTAs see a burst of connection attempts."],"args":[],"examples":[{"title":"Retry deferred","args":{}}],"search_terms":[],"command":{"binary":"postqueue","argv":["-f"]}},{"id":"postfix.maillog_grep","title":"grep mail.log for queue-id / address","summary":"List all mail-log entries matching a string.","description":"List all mail-log entries matching a string.","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"pattern","type":"string","required":true,"description":"Literal match.","validation":{"pattern":"^[a-zA-Z0-9_.@\\-]{1,128}$"}}],"examples":[{"title":"Trace one recipient","args":{"pattern":"user@example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -r /var/log/mail.log ]; then log=/var/log/mail.log\nelif [ -r /var/log/maillog ]; then log=/var/log/maillog\nelse echo \"no readable mail log at /var/log/mail.log or /var/log/maillog\" >&2; exit 1\nfi\ngrep -F \"$P\" \"$log\" | head -2000\n"]}},{"id":"postfix.maillog_tail","title":"tail mail.log","summary":"Tail the last N lines of the mail log.","description":"Tail the last N lines of the mail log.","kind":"exec","risk":"medium","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} /var/log/mail.log 2>/dev/null || tail -n {{ args.lines }} /var/log/maillog"]}},{"id":"postfix.mailq","title":"mailq (current queue)","summary":"Show the Postfix mail queue — pending, deferred, hold counts.","description":"Show the Postfix mail queue — pending, deferred, hold counts.","kind":"exec","risk":"low","side_effects":["One mailq call.","Read-only."],"args":[],"examples":[{"title":"Queue snapshot","args":{}}],"search_terms":[],"command":{"binary":"mailq","argv":[]}},{"id":"postfix.postcat_qid","title":"postcat -q <queue-id>","summary":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads one spool file.","Read-only — message content may include user PII."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Postfix queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Show one deferred message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postcat","argv":["-q","{{ args.queue_id }}"]}},{"id":"postfix.postconf","title":"postconf -n","summary":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One postconf call.","Read-only, but dumps every non-default parameter (may include inline credentials)."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"postconf","argv":["-n"]}},{"id":"postfix.postsuper_hold","title":"postsuper -h <qid>","summary":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","description":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","kind":"exec","risk":"medium","side_effects":["Message moved to hold queue.","No delivery attempts until released."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Hold a message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-h","{{ args.qid }}"]}},{"id":"postfix.postsuper_release","title":"postsuper -H <qid>","summary":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","description":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","kind":"exec","risk":"medium","side_effects":["Message moved from hold to active.","Delivery attempted on next tick."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Release a held message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-H","{{ args.qid }}"]}},{"id":"postfix.postsuper_requeue","title":"postsuper -r <qid|ALL>","summary":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","description":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","kind":"exec","risk":"high","side_effects":["Message(s) moved from deferred to active.","Delivery attempted on next tick.","ALL can cause a delivery burst on a large queue."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID, or the literal \"ALL\".","validation":{"pattern":"^([A-F0-9]{6,20}|ALL)$"}}],"examples":[{"title":"Requeue one","args":{"qid":"3ABCDEF12345"}},{"title":"Requeue all deferred","args":{"qid":"ALL"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-r","{{ args.qid }}"]}},{"id":"postfix.qshape","title":"qshape (queue by domain x age)","summary":"Show bucketed queue counts by destination + age.","description":"Show bucketed queue counts by destination + age.","kind":"exec","risk":"low","side_effects":["One qshape call.","Read-only."],"args":[{"name":"queue","type":"string","required":false,"default":"deferred","description":"Queue name.","validation":{"enum":["incoming","active","deferred","hold"]}}],"examples":[{"title":"Deferred shape","args":{"queue":"deferred"}}],"search_terms":[],"command":{"binary":"qshape","argv":["{{ args.queue }}"]}},{"id":"postfix.queue_counts","title":"Per-queue message counts","summary":"Count messages in incoming/active/deferred/hold queues.","description":"Count messages in incoming/active/deferred/hold queues.","kind":"exec","risk":"low","side_effects":["Counts files in /var/spool/postfix/*.","Read-only."],"args":[],"examples":[{"title":"Counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d /var/spool/postfix ] || { echo \"no postfix spool at /var/spool/postfix\" >&2; exit 1; }\nfor q in incoming active deferred hold; do n=$(find /var/spool/postfix/$q -type f 2>/dev/null | wc -l); echo \"$q: $n\"; done\n"]}},{"id":"postfix.reload","title":"postfix reload","summary":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","description":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","kind":"exec","risk":"high","side_effects":["Config re-read.","In-flight deliveries unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["reload"]}}],"previous_versions":[{"version":"0.1.15","content_hash":"sha256:7159df7e4903123d2d947e4ce7b75fb3f445a187eac5417a601175575991fc81","tarball_url":"https://registry.emisar.dev/v1/packs/postfix/0.1.15/7159df7e4903123d2d947e4ce7b75fb3f445a187eac5417a601175575991fc81/pack.tar.gz","actions":[{"id":"postfix.check_config","title":"postfix check","summary":"Validate Postfix configuration files.","description":"Validate Postfix configuration files.","kind":"exec","risk":"low","side_effects":["Reads main.cf + master.cf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["check"]}},{"id":"postfix.delete_qid","title":"postsuper -d <queue-id>","summary":"Delete one queued message. Permanent — message is lost.","description":"Delete one queued message. Permanent — message is lost.","kind":"exec","risk":"critical","side_effects":["Message is removed from the queue.","Sender is NOT notified."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Drop one stuck message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-d","{{ args.queue_id }}"]}},{"id":"postfix.flush_queue","title":"postqueue -f (retry all deferred)","summary":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","description":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","kind":"exec","risk":"high","side_effects":["Every deferred message is re-attempted immediately.","Downstream MTAs see a burst of connection attempts."],"args":[],"examples":[{"title":"Retry deferred","args":{}}],"search_terms":[],"command":{"binary":"postqueue","argv":["-f"]}},{"id":"postfix.maillog_grep","title":"grep mail.log for queue-id / address","summary":"List all mail-log entries matching a string.","description":"List all mail-log entries matching a string.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"pattern","type":"string","required":true,"description":"Literal match.","validation":{"pattern":"^[a-zA-Z0-9_.@\\-]{1,128}$"}}],"examples":[{"title":"Trace one recipient","args":{"pattern":"user@example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -r /var/log/mail.log ]; then log=/var/log/mail.log\nelif [ -r /var/log/maillog ]; then log=/var/log/maillog\nelse echo \"no readable mail log at /var/log/mail.log or /var/log/maillog\" >&2; exit 1\nfi\ngrep -F \"$P\" \"$log\" | head -2000\n"]}},{"id":"postfix.maillog_tail","title":"tail mail.log","summary":"Tail the last N lines of the mail log.","description":"Tail the last N lines of the mail log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} /var/log/mail.log 2>/dev/null || tail -n {{ args.lines }} /var/log/maillog"]}},{"id":"postfix.mailq","title":"mailq (current queue)","summary":"Show the Postfix mail queue — pending, deferred, hold counts.","description":"Show the Postfix mail queue — pending, deferred, hold counts.","kind":"exec","risk":"low","side_effects":["One mailq call.","Read-only."],"args":[],"examples":[{"title":"Queue snapshot","args":{}}],"search_terms":[],"command":{"binary":"mailq","argv":[]}},{"id":"postfix.postcat_qid","title":"postcat -q <queue-id>","summary":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads one spool file.","Read-only — message content may include user PII."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Postfix queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Show one deferred message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postcat","argv":["-q","{{ args.queue_id }}"]}},{"id":"postfix.postconf","title":"postconf -n","summary":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One postconf call.","Read-only, but dumps every non-default parameter (may include inline credentials)."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"postconf","argv":["-n"]}},{"id":"postfix.postsuper_hold","title":"postsuper -h <qid>","summary":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","description":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","kind":"exec","risk":"medium","side_effects":["Message moved to hold queue.","No delivery attempts until released."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Hold a message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-h","{{ args.qid }}"]}},{"id":"postfix.postsuper_release","title":"postsuper -H <qid>","summary":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","description":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","kind":"exec","risk":"medium","side_effects":["Message moved from hold to active.","Delivery attempted on next tick."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Release a held message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-H","{{ args.qid }}"]}},{"id":"postfix.postsuper_requeue","title":"postsuper -r <qid|ALL>","summary":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","description":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","kind":"exec","risk":"high","side_effects":["Message(s) moved from deferred to active.","Delivery attempted on next tick.","ALL can cause a delivery burst on a large queue."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID, or the literal \"ALL\".","validation":{"pattern":"^([A-F0-9]{6,20}|ALL)$"}}],"examples":[{"title":"Requeue one","args":{"qid":"3ABCDEF12345"}},{"title":"Requeue all deferred","args":{"qid":"ALL"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-r","{{ args.qid }}"]}},{"id":"postfix.qshape","title":"qshape (queue by domain x age)","summary":"Show bucketed queue counts by destination + age.","description":"Show bucketed queue counts by destination + age.","kind":"exec","risk":"low","side_effects":["One qshape call.","Read-only."],"args":[{"name":"queue","type":"string","required":false,"default":"deferred","description":"Queue name.","validation":{"enum":["incoming","active","deferred","hold"]}}],"examples":[{"title":"Deferred shape","args":{"queue":"deferred"}}],"search_terms":[],"command":{"binary":"qshape","argv":["{{ args.queue }}"]}},{"id":"postfix.queue_counts","title":"Per-queue message counts","summary":"Count messages in incoming/active/deferred/hold queues.","description":"Count messages in incoming/active/deferred/hold queues.","kind":"exec","risk":"low","side_effects":["Counts files in /var/spool/postfix/*.","Read-only."],"args":[],"examples":[{"title":"Counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d /var/spool/postfix ] || { echo \"no postfix spool at /var/spool/postfix\" >&2; exit 1; }\nfor q in incoming active deferred hold; do n=$(find /var/spool/postfix/$q -type f 2>/dev/null | wc -l); echo \"$q: $n\"; done\n"]}},{"id":"postfix.reload","title":"postfix reload","summary":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","description":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","kind":"exec","risk":"high","side_effects":["Config re-read.","In-flight deliveries unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["reload"]}}]},{"version":"0.1.13","content_hash":"sha256:dc2a34a592d5f275b0a388a4ee942cf96a3ffa087e8e617c217ef2fe489c80d0","tarball_url":"https://registry.emisar.dev/v1/packs/postfix/0.1.13/dc2a34a592d5f275b0a388a4ee942cf96a3ffa087e8e617c217ef2fe489c80d0/pack.tar.gz","actions":[{"id":"postfix.check_config","title":"postfix check","summary":"Validate Postfix configuration files.","description":"Validate Postfix configuration files.","kind":"exec","risk":"low","side_effects":["Reads main.cf + master.cf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["check"]}},{"id":"postfix.delete_qid","title":"postsuper -d <queue-id>","summary":"Delete one queued message. Permanent — message is lost.","description":"Delete one queued message. Permanent — message is lost.","kind":"exec","risk":"critical","side_effects":["Message is removed from the queue.","Sender is NOT notified."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Drop one stuck message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-d","{{ args.queue_id }}"]}},{"id":"postfix.flush_queue","title":"postqueue -f (retry all deferred)","summary":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","description":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","kind":"exec","risk":"high","side_effects":["Every deferred message is re-attempted immediately.","Downstream MTAs see a burst of connection attempts."],"args":[],"examples":[{"title":"Retry deferred","args":{}}],"search_terms":[],"command":{"binary":"postqueue","argv":["-f"]}},{"id":"postfix.maillog_grep","title":"grep mail.log for queue-id / address","summary":"List all mail-log entries matching a string.","description":"List all mail-log entries matching a string.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"pattern","type":"string","required":true,"description":"Literal match.","validation":{"pattern":"^[a-zA-Z0-9_.@\\-]{1,128}$"}}],"examples":[{"title":"Trace one recipient","args":{"pattern":"user@example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -r /var/log/mail.log ]; then log=/var/log/mail.log\nelif [ -r /var/log/maillog ]; then log=/var/log/maillog\nelse echo \"no readable mail log at /var/log/mail.log or /var/log/maillog\" >&2; exit 1\nfi\ngrep -F \"$P\" \"$log\" | head -2000\n"]}},{"id":"postfix.maillog_tail","title":"tail mail.log","summary":"Tail the last N lines of the mail log.","description":"Tail the last N lines of the mail log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} /var/log/mail.log 2>/dev/null || tail -n {{ args.lines }} /var/log/maillog"]}},{"id":"postfix.mailq","title":"mailq (current queue)","summary":"Show the Postfix mail queue — pending, deferred, hold counts.","description":"Show the Postfix mail queue — pending, deferred, hold counts.","kind":"exec","risk":"low","side_effects":["One mailq call.","Read-only."],"args":[],"examples":[{"title":"Queue snapshot","args":{}}],"search_terms":[],"command":{"binary":"mailq","argv":[]}},{"id":"postfix.postcat_qid","title":"postcat -q <queue-id>","summary":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads one spool file.","Read-only — message content may include user PII."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Postfix queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Show one deferred message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postcat","argv":["-q","{{ args.queue_id }}"]}},{"id":"postfix.postconf","title":"postconf -n","summary":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One postconf call.","Read-only, but dumps every non-default parameter (may include inline credentials)."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"postconf","argv":["-n"]}},{"id":"postfix.postsuper_hold","title":"postsuper -h <qid>","summary":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","description":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","kind":"exec","risk":"medium","side_effects":["Message moved to hold queue.","No delivery attempts until released."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Hold a message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-h","{{ args.qid }}"]}},{"id":"postfix.postsuper_release","title":"postsuper -H <qid>","summary":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","description":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","kind":"exec","risk":"medium","side_effects":["Message moved from hold to active.","Delivery attempted on next tick."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Release a held message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-H","{{ args.qid }}"]}},{"id":"postfix.postsuper_requeue","title":"postsuper -r <qid|ALL>","summary":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","description":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","kind":"exec","risk":"high","side_effects":["Message(s) moved from deferred to active.","Delivery attempted on next tick.","ALL can cause a delivery burst on a large queue."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID, or the literal \"ALL\".","validation":{"pattern":"^([A-F0-9]{6,20}|ALL)$"}}],"examples":[{"title":"Requeue one","args":{"qid":"3ABCDEF12345"}},{"title":"Requeue all deferred","args":{"qid":"ALL"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-r","{{ args.qid }}"]}},{"id":"postfix.qshape","title":"qshape (queue by domain x age)","summary":"Show bucketed queue counts by destination + age.","description":"Show bucketed queue counts by destination + age.","kind":"exec","risk":"low","side_effects":["One qshape call.","Read-only."],"args":[{"name":"queue","type":"string","required":false,"default":"deferred","description":"Queue name.","validation":{"enum":["incoming","active","deferred","hold"]}}],"examples":[{"title":"Deferred shape","args":{"queue":"deferred"}}],"search_terms":[],"command":{"binary":"qshape","argv":["{{ args.queue }}"]}},{"id":"postfix.queue_counts","title":"Per-queue message counts","summary":"Count messages in incoming/active/deferred/hold queues.","description":"Count messages in incoming/active/deferred/hold queues.","kind":"exec","risk":"low","side_effects":["Counts files in /var/spool/postfix/*.","Read-only."],"args":[],"examples":[{"title":"Counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d /var/spool/postfix ] || { echo \"no postfix spool at /var/spool/postfix\" >&2; exit 1; }\nfor q in incoming active deferred hold; do n=$(find /var/spool/postfix/$q -type f 2>/dev/null | wc -l); echo \"$q: $n\"; done\n"]}},{"id":"postfix.reload","title":"postfix reload","summary":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","description":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","kind":"exec","risk":"high","side_effects":["Config re-read.","In-flight deliveries unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["reload"]}}]},{"version":"0.1.12","content_hash":"sha256:3a486e26705b9da4fd8ae6d6dcfe7fac5324ddd72dd636fecc16a07683818c4c","tarball_url":"https://registry.emisar.dev/v1/packs/postfix/0.1.12/3a486e26705b9da4fd8ae6d6dcfe7fac5324ddd72dd636fecc16a07683818c4c/pack.tar.gz","actions":[{"id":"postfix.check_config","title":"postfix check","summary":"Validate Postfix configuration files.","description":"Validate Postfix configuration files.","kind":"exec","risk":"low","side_effects":["Reads main.cf + master.cf.","Read-only."],"args":[],"examples":[{"title":"Check config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["check"]}},{"id":"postfix.delete_qid","title":"postsuper -d <queue-id>","summary":"Delete one queued message. Permanent — message is lost.","description":"Delete one queued message. Permanent — message is lost.","kind":"exec","risk":"critical","side_effects":["Message is removed from the queue.","Sender is NOT notified."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Drop one stuck message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-d","{{ args.queue_id }}"]}},{"id":"postfix.flush_queue","title":"postqueue -f (retry all deferred)","summary":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","description":"Force retry of every deferred message. Can cause a thundering-herd toward downstream SMTP.","kind":"exec","risk":"high","side_effects":["Every deferred message is re-attempted immediately.","Downstream MTAs see a burst of connection attempts."],"args":[],"examples":[{"title":"Retry deferred","args":{}}],"search_terms":[],"command":{"binary":"postqueue","argv":["-f"]}},{"id":"postfix.maillog_grep","title":"grep mail.log for queue-id / address","summary":"List all mail-log entries matching a string.","description":"List all mail-log entries matching a string.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"pattern","type":"string","required":true,"description":"Literal match.","validation":{"pattern":"^[a-zA-Z0-9_.@\\-]{1,128}$"}}],"examples":[{"title":"Trace one recipient","args":{"pattern":"user@example.com"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -r /var/log/mail.log ]; then log=/var/log/mail.log\nelif [ -r /var/log/maillog ]; then log=/var/log/maillog\nelse echo \"no readable mail log at /var/log/mail.log or /var/log/maillog\" >&2; exit 1\nfi\ngrep -F \"$P\" \"$log\" | head -2000\n"]}},{"id":"postfix.maillog_tail","title":"tail mail.log","summary":"Tail the last N lines of the mail log.","description":"Tail the last N lines of the mail log.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":200,"description":"Lines.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Last 200","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","tail -n {{ args.lines }} /var/log/mail.log 2>/dev/null || tail -n {{ args.lines }} /var/log/maillog"]}},{"id":"postfix.mailq","title":"mailq (current queue)","summary":"Show the Postfix mail queue — pending, deferred, hold counts.","description":"Show the Postfix mail queue — pending, deferred, hold counts.","kind":"exec","risk":"low","side_effects":["One mailq call.","Read-only."],"args":[],"examples":[{"title":"Queue snapshot","args":{}}],"search_terms":[],"command":{"binary":"mailq","argv":[]}},{"id":"postfix.postcat_qid","title":"postcat -q <queue-id>","summary":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Decode one queued message — headers + body. Message content is inherently sensitive (user PII, and bodies routinely carry password resets, tokens, and other credentials). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["Reads one spool file.","Read-only — message content may include user PII."],"args":[{"name":"queue_id","type":"string","required":true,"description":"Postfix queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Show one deferred message","args":{"queue_id":"3F7A8C001234"}}],"search_terms":[],"command":{"binary":"postcat","argv":["-q","{{ args.queue_id }}"]}},{"id":"postfix.postconf","title":"postconf -n","summary":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","description":"Show non-default Postfix config (`postconf -n`). A full parameter dump: `smtp_sasl_password_maps`-style parameters can inline `static:` credentials, so this can surface secrets. The runner's redaction is a pattern-bound backstop, not a guarantee.","kind":"exec","risk":"high","side_effects":["One postconf call.","Read-only, but dumps every non-default parameter (may include inline credentials)."],"args":[],"examples":[{"title":"Effective config","args":{}}],"search_terms":[],"command":{"binary":"postconf","argv":["-n"]}},{"id":"postfix.postsuper_hold","title":"postsuper -h <qid>","summary":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","description":"Move one message into the hold queue. The message is not delivered until released with postsuper_release. Used when a message needs to be inspected without redelivering on every queue tick.","kind":"exec","risk":"medium","side_effects":["Message moved to hold queue.","No delivery attempts until released."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Hold a message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-h","{{ args.qid }}"]}},{"id":"postfix.postsuper_release","title":"postsuper -H <qid>","summary":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","description":"Release one held message back to active. Postfix will attempt delivery on the next queue scan.","kind":"exec","risk":"medium","side_effects":["Message moved from hold to active.","Delivery attempted on next tick."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID.","validation":{"pattern":"^[A-F0-9]{6,20}$"}}],"examples":[{"title":"Release a held message","args":{"qid":"3ABCDEF12345"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-H","{{ args.qid }}"]}},{"id":"postfix.postsuper_requeue","title":"postsuper -r <qid|ALL>","summary":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","description":"Re-queue one message (or ALL deferred). The message is re-classified from the deferred queue back to active, retrying delivery.","kind":"exec","risk":"high","side_effects":["Message(s) moved from deferred to active.","Delivery attempted on next tick.","ALL can cause a delivery burst on a large queue."],"args":[{"name":"qid","type":"string","required":true,"description":"Queue ID, or the literal \"ALL\".","validation":{"pattern":"^([A-F0-9]{6,20}|ALL)$"}}],"examples":[{"title":"Requeue one","args":{"qid":"3ABCDEF12345"}},{"title":"Requeue all deferred","args":{"qid":"ALL"}}],"search_terms":[],"command":{"binary":"postsuper","argv":["-r","{{ args.qid }}"]}},{"id":"postfix.qshape","title":"qshape (queue by domain x age)","summary":"Show bucketed queue counts by destination + age.","description":"Show bucketed queue counts by destination + age.","kind":"exec","risk":"low","side_effects":["One qshape call.","Read-only."],"args":[{"name":"queue","type":"string","required":false,"default":"deferred","description":"Queue name.","validation":{"enum":["incoming","active","deferred","hold"]}}],"examples":[{"title":"Deferred shape","args":{"queue":"deferred"}}],"search_terms":[],"command":{"binary":"qshape","argv":["{{ args.queue }}"]}},{"id":"postfix.queue_counts","title":"Per-queue message counts","summary":"Count messages in incoming/active/deferred/hold queues.","description":"Count messages in incoming/active/deferred/hold queues.","kind":"exec","risk":"low","side_effects":["Counts files in /var/spool/postfix/*.","Read-only."],"args":[],"examples":[{"title":"Counts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d /var/spool/postfix ] || { echo \"no postfix spool at /var/spool/postfix\" >&2; exit 1; }\nfor q in incoming active deferred hold; do n=$(find /var/spool/postfix/$q -type f 2>/dev/null | wc -l); echo \"$q: $n\"; done\n"]}},{"id":"postfix.reload","title":"postfix reload","summary":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","description":"Tell Postfix to re-read main.cf and master.cf. Existing deliveries finish on the old config; new ones use the new. No downtime.","kind":"exec","risk":"high","side_effects":["Config re-read.","In-flight deliveries unaffected."],"args":[],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"postfix","argv":["reload"]}}]}],"retired_below":"0.1.11"},{"id":"postgres","name":"Postgres operations","version":"0.2.17","description":"Deep Postgres operations — activity introspection, session/lock diagnostics, table + index analytics (bloat, dead tuples, unused indexes), WAL + replication state, progress views, EXPLAIN, and a curated set of operator-tier mutators (cancel/terminate backend, ANALYZE, VACUUM, REINDEX CONCURRENTLY). Authenticates via PG* env vars on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/postgres","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/postgres","content_hash":"sha256:06ffccbe346e4278af5e1048cecf311e89cf3b18221c367f3c32b6cd3c510b1b","tarball_url":"https://registry.emisar.dev/v1/packs/postgres/0.2.17/06ffccbe346e4278af5e1048cecf311e89cf3b18221c367f3c32b6cd3c510b1b/pack.tar.gz","requires":{"os":["linux"],"binaries":["psql"]},"detect":{"binaries":[],"processes":["postgres"],"ports":[5432]},"setup":{"summary":"Authenticates via libpq PG* environment variables on the runner host. psql reads them directly — the runner only forwards the ones you allowlist in `inherit_env`.","env":[{"name":"PGHOST","required":true,"description":"Server host or socket directory.","example":"db.internal"},{"name":"PGPORT","description":"Server port.","default":"5432"},{"name":"PGUSER","required":true,"description":"Role to connect as; needs privileges for the actions you enable."},{"name":"PGPASSWORD","description":"Password for `PGUSER`. Omit if using `~/.pgpass` or trust/peer auth."},{"name":"PGDATABASE","description":"Default database.","default":"same as `PGUSER`"}],"notes":["Create the role with CREATE ROLE emisar LOGIN PASSWORD '...'; GRANT pg_monitor TO emisar; — pg_monitor covers the read actions without handing out superuser.","Alternative to `PGPASSWORD`: put credentials in `~/.pgpass` (mode 0600) on the runner host — read from disk, so it needs no `inherit_env` entry.","High-risk mutators (terminate_backend, vacuum_table, reindex_concurrent) need a role with the matching privileges."],"verify":"postgres.uptime"},"actions":[{"id":"postgres.activity_detail","title":"pg_stat_activity (per-backend)","summary":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT against pg_stat_activity.","No locks."],"args":[],"examples":[{"title":"All backends","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, state, wait_event_type, wait_event, EXTRACT(EPOCH FROM (now()-query_start))::int AS query_age_sec, EXTRACT(EPOCH FROM (now()-state_change))::int AS state_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 200;"]}},{"id":"postgres.activity_states","title":"Backend counts by state","summary":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","description":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"State counts","args":{}}],"search_terms":["too many connections","connection pileup"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, count(*) AS n FROM pg_stat_activity GROUP BY state ORDER BY n DESC;"]}},{"id":"postgres.analyze_table","title":"ANALYZE <schema>.<table>","summary":"Refresh planner statistics for one table.","description":"Refresh planner statistics for one table.","kind":"exec","risk":"medium","side_effects":["Reads sample rows from the table.","Updates pg_class/pg_statistic.","No locks beyond ShareUpdateExclusiveLock (DML continues)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Refresh stats","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","ANALYZE VERBOSE {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.backend_holding_xmin","title":"Backend holding the oldest xmin","summary":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum's enemy","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, state, backend_xmin, EXTRACT(EPOCH FROM (now()-xact_start))::int AS xact_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE backend_xmin IS NOT NULL ORDER BY backend_xmin::text::bigint ASC LIMIT 5;"]}},{"id":"postgres.bgwriter_stats","title":"pg_stat_bgwriter","summary":"Show background writer + checkpoint stats since stats reset.","description":"Show background writer + checkpoint stats since stats reset.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"bgwriter","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_bgwriter;"]}},{"id":"postgres.cancel_query","title":"Cancel a running query","summary":"Send SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","description":"Send SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","kind":"exec","risk":"high","side_effects":["The target backend's current query is cancelled with an ERROR.","The client connection stays open and the transaction is rolled back.","Does not affect other sessions."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID to cancel (see pg_stat_activity).","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Cancel backend 12345","args":{"pid":12345}}],"search_terms":["kill query","stop query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_cancel_backend({{ args.pid }});"]}},{"id":"postgres.connections","title":"Postgres connection summary","summary":"Count pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","description":"Count pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks held."],"args":[],"examples":[{"title":"Spot idle-in-transaction backends","args":{}}],"search_terms":["too many connections","connection pileup","max_connections","connection storm"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, application_name, count(*) AS n FROM pg_stat_activity GROUP BY state, application_name ORDER BY n DESC LIMIT 50;"]}},{"id":"postgres.database_stats","title":"pg_stat_database","summary":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","description":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Per-DB stats","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, xact_commit, xact_rollback, blks_read, blks_hit, ROUND(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS cache_hit_pct, tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted, deadlocks, conflicts, temp_files, pg_size_pretty(temp_bytes) AS temp_size FROM pg_stat_database WHERE datname IS NOT NULL ORDER BY (blks_read + blks_hit) DESC LIMIT 30;"]}},{"id":"postgres.db_sizes","title":"All databases by size","summary":"List every database with pg_database_size.","description":"List every database with pg_database_size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":["database out of space","db size","disk usage"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE NOT datistemplate ORDER BY pg_database_size(datname) DESC;"]}},{"id":"postgres.dead_tuples_top","title":"Top tables by dead-tuple ratio","summary":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","description":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Bloat suspects","args":{}}],"search_terms":["table bloat","autovacuum not keeping up"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_live_tup, n_dead_tup, ROUND(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE n_live_tup + n_dead_tup > 10000 ORDER BY n_dead_tup DESC LIMIT 30;"]}},{"id":"postgres.duplicate_indexes","title":"Duplicate indexes (same column set)","summary":"List indexes covering identical columns. One per group is redundant; drop after verifying.","description":"List indexes covering identical columns. One per group is redundant; drop after verifying.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Duplicates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT array_agg(indexrelid::regclass::text ORDER BY indexrelid) AS indexes, indrelid::regclass AS table, indkey::text AS columns FROM pg_index GROUP BY indrelid, indkey HAVING count(*) > 1 LIMIT 50;"]}},{"id":"postgres.explain_analyze","title":"EXPLAIN ANALYZE (FORMAT JSON) <query>","summary":"Run EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","description":"Run EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","kind":"exec","risk":"high","side_effects":["Query is executed with timing instrumentation, inside a read-only transaction.","Slower than EXPLAIN-only; a heavy query loads the server for up to the timeout.","Data-modifying statements and CTEs (INSERT/UPDATE/DELETE) are rejected by the read-only transaction."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT or WITH statement (executed read-only).","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Analyze count query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) {{ args.query }}"]}},{"id":"postgres.explain_query","title":"EXPLAIN (FORMAT JSON) <query>","summary":"Show the plan-only EXPLAIN. The query is NOT executed.","description":"Show the plan-only EXPLAIN. The query is NOT executed.","kind":"exec","risk":"low","side_effects":["Parses + plans the query.","Read-only — query body is not executed."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT statement.","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Plan one query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (FORMAT JSON, VERBOSE) {{ args.query }}"]}},{"id":"postgres.extensions_installed","title":"Installed extensions","summary":"List currently-loaded extensions with versions + schema.","description":"List currently-loaded extensions with versions + schema.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Extensions","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT extname, extversion, n.nspname AS schema FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace ORDER BY extname;"]}},{"id":"postgres.hot_update_ratio","title":"HOT update ratio per table","summary":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","description":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"HOT update ratios","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_tup_upd, n_tup_hot_upd, ROUND(100.0 * n_tup_hot_upd / NULLIF(n_tup_upd, 0), 2) AS hot_pct FROM pg_stat_user_tables WHERE n_tup_upd > 10000 ORDER BY n_tup_upd DESC LIMIT 30;"]}},{"id":"postgres.idle_in_transaction","title":"Idle-in-transaction backends","summary":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"IIT offenders","args":{}}],"search_terms":["stuck transaction","uncommitted transaction","connection leak"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, EXTRACT(EPOCH FROM (now()-state_change))::int AS idle_sec, substring(query, 1, 300) AS last_query FROM pg_stat_activity WHERE state IN ('idle in transaction','idle in transaction (aborted)') ORDER BY state_change ASC LIMIT 100;"]}},{"id":"postgres.index_sizes","title":"Top 50 indexes by size","summary":"List the largest indexes — candidates for bloat investigation.","description":"List the largest indexes — candidates for bloat investigation.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Largest indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, s.idx_scan FROM pg_stat_user_indexes s ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.invalid_indexes","title":"Invalid indexes (indisvalid = false)","summary":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","description":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Broken indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname || '.' || c.relname AS index, t.relname AS table, pg_size_pretty(pg_relation_size(c.oid)) AS size FROM pg_index i JOIN pg_class c ON c.oid = i.indexrelid JOIN pg_class t ON t.oid = i.indrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE NOT i.indisvalid;"]}},{"id":"postgres.is_in_recovery","title":"pg_is_in_recovery()","summary":"Show whether this instance is a replica (boolean — true if in recovery).","description":"Show whether this instance is a replica (boolean — true if in recovery).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recovery?","args":{}}],"search_terms":["primary or replica","is this the primary"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery();"]}},{"id":"postgres.kill_idle","title":"Terminate idle-in-transaction backends","summary":"Call `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","description":"Call `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","kind":"exec","risk":"high","side_effects":["SIGTERMs every matching backend.","In-flight transactions on those connections roll back.","Clients see a closed connection and must reconnect."],"args":[{"name":"older_than_seconds","type":"integer","required":false,"default":600,"description":"Only terminate idle-in-transaction backends older than this (default 10 min).","validation":{"min":60,"max":86400}}],"examples":[{"title":"Kill anything idle-in-transaction > 10 min","args":{}},{"title":"Aggressive — anything > 60 s","args":{"older_than_seconds":60}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND state_change < now() - interval '{{ args.older_than_seconds }} seconds';"]}},{"id":"postgres.largest_tables_full","title":"Largest tables with vacuum/dead-tuple info","summary":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","description":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_stat_user_tables.","Read-only."],"args":[],"examples":[{"title":"Top tables","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, pg_size_pretty(pg_total_relation_size(relid)) AS total_size, pg_size_pretty(pg_relation_size(relid)) AS table_size, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 50;"]}},{"id":"postgres.last_vacuum_per_table","title":"Last vacuum/analyze per table","summary":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","description":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum freshness","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, n_live_tup, n_dead_tup FROM pg_stat_user_tables ORDER BY COALESCE(last_autovacuum, last_vacuum) ASC NULLS FIRST LIMIT 50;"]}},{"id":"postgres.lock_blocking_chains","title":"Blocker → blocked chains","summary":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT joining pg_locks.","Read-only."],"args":[],"examples":[{"title":"Lock chains","args":{}}],"search_terms":["lock contention","who is blocking","waiting on lock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocking.pid AS blocker_pid, blocked.usename AS blocked_user, blocking.usename AS blocker_user, blocked.wait_event_type, blocked.wait_event, substring(blocked.query, 1, 200) AS blocked_query, substring(blocking.query, 1, 200) AS blocker_query FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));"]}},{"id":"postgres.locks","title":"Blocking lock graph","summary":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim. Rated medium because the truncated SQL of each side is live query text, which can include literal request values no redaction list can enumerate.","description":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim. Rated medium because the truncated SQL of each side is live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT joining pg_locks and pg_stat_activity.","No locks held by this query."],"args":[],"examples":[{"title":"What's currently blocked?","args":{}}],"search_terms":["lock contention","waiting on lock","deadlock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocked.usename AS blocked_user, left(blocked.query, 120) AS blocked_query, blocking.pid AS blocking_pid, blocking.usename AS blocking_user, left(blocking.query, 120) AS blocking_query, blocked.wait_event_type, blocked.wait_event FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid)) WHERE blocked.wait_event_type IS NOT NULL ORDER BY blocked.pid LIMIT 50;"]}},{"id":"postgres.longest_running_queries","title":"Top 20 by query age","summary":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","description":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work. Rated medium because the output carries live query text, which can include literal request values no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Long-runners","args":{}}],"search_terms":["db is slow","database slow","slow db","long running query","stuck query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, EXTRACT(EPOCH FROM (now()-query_start))::int AS age_sec, wait_event_type, wait_event, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE state='active' AND pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 20;"]}},{"id":"postgres.pg_hba_rules","title":"pg_hba_file_rules","summary":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","description":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only — LDAP/RADIUS auth secrets are stripped from the options column."],"args":[],"examples":[{"title":"Hba rules","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT line_number, type, database, user_name, address, netmask, auth_method, array(SELECT o FROM unnest(options) AS o WHERE o NOT LIKE 'ldapbindpasswd=%' AND o NOT LIKE 'radiussecrets=%') AS options, error FROM pg_hba_file_rules ORDER BY line_number;"]}},{"id":"postgres.pg_stat_statements_reset","title":"pg_stat_statements_reset()","summary":"Clear accumulated pg_stat_statements counters. Use to start a clean measurement window.","description":"Clear accumulated pg_stat_statements counters. Use to start a clean measurement window.","kind":"exec","risk":"medium","side_effects":["All accumulated counters are reset to 0.","Future queries start from a clean baseline."],"args":[],"examples":[{"title":"Reset","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_stat_statements_reset();"]}},{"id":"postgres.pg_stat_statements_top","title":"Top statements by total time","summary":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded. Stays low — normalized queries replace literals with `$1`/`$2`, so the output is the query shape, not real request data.","description":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded. Stays low — normalized queries replace literals with `$1`/`$2`, so the output is the query shape, not real request data.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","Read-only."],"args":[],"examples":[{"title":"Heavy hitters","args":{}}],"search_terms":["db is slow","database slow","slow db","expensive queries"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, ROUND(total_exec_time::numeric, 0) AS total_ms, ROUND(mean_exec_time::numeric, 1) AS mean_ms, rows, ROUND(100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0), 1) AS cache_hit_pct, substring(query, 1, 300) AS query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 30;"]}},{"id":"postgres.progress_create_index","title":"pg_stat_progress_create_index","summary":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","description":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live CREATE INDEXes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, p.index_relid::regclass AS index, phase, blocks_total, blocks_done, tuples_total, tuples_done FROM pg_stat_progress_create_index p;"]}},{"id":"postgres.progress_vacuum","title":"pg_stat_progress_vacuum","summary":"Show in-flight VACUUMs with phase + heap_blks_scanned.","description":"Show in-flight VACUUMs with phase + heap_blks_scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live VACUUMs","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, num_dead_tuples FROM pg_stat_progress_vacuum p;"]}},{"id":"postgres.reindex_concurrent","title":"REINDEX INDEX CONCURRENTLY <schema>.<index>","summary":"Rebuild one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","description":"Rebuild one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","kind":"exec","risk":"high","side_effects":["New copy of the index is built alongside.","Old index dropped at end; brief lock at swap.","On failure, an _ccnew suffix index may be left behind."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Rebuild bloated index","args":{"index":"orders_user_id_idx","schema":"public"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","REINDEX INDEX CONCURRENTLY {{ args.schema }}.{{ args.index }};"]}},{"id":"postgres.reload_conf","title":"Reload postgresql.conf","summary":"Call `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","description":"Call `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","kind":"exec","risk":"high","side_effects":["Server re-reads postgresql.conf and pg_hba.conf.","Active sessions keep their old settings until they reconnect for `user`-context settings; sighup-context settings apply immediately.","A malformed config logs a warning and keeps the previous values."],"args":[],"examples":[{"title":"Reload after editing postgresql.conf","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_reload_conf();"]}},{"id":"postgres.replication_lag","title":"Replication lag (primary view)","summary":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","description":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_replication.","No locks held."],"args":[],"examples":[{"title":"How far behind are my replicas?","args":{}}],"search_terms":["replica out of sync","replication behind","standby lag"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT application_name, client_addr, state, sync_state, pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) AS sent_lag, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag FROM pg_stat_replication ORDER BY application_name;"]}},{"id":"postgres.replication_slots","title":"pg_replication_slots","summary":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","description":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slots","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT slot_name, slot_type, plugin, database, active, restart_lsn, confirmed_flush_lsn, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;"]}},{"id":"postgres.seq_scan_offenders","title":"Tables with high seq-scan ratio","summary":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","description":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Seq scan offenders","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, seq_scan, idx_scan, seq_tup_read, idx_tup_fetch, ROUND(100.0 * seq_scan / NULLIF(seq_scan + idx_scan, 0), 2) AS seq_scan_pct, n_live_tup FROM pg_stat_user_tables WHERE seq_scan + idx_scan > 0 AND seq_tup_read > 100000 ORDER BY seq_tup_read DESC LIMIT 30;"]}},{"id":"postgres.settings_non_default","title":"pg_settings (non-default)","summary":"List settings the operator has changed from the compiled defaults.","description":"List settings the operator has changed from the compiled defaults.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Non-default settings","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT name, setting, unit, source, sourcefile, sourceline FROM pg_settings WHERE source NOT IN ('default', 'override') ORDER BY name;"]}},{"id":"postgres.slow_queries","title":"Top slow queries from pg_stat_statements","summary":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only. Stays low — pg_stat_statements fingerprints replace literals with `$1`/`$2`, so the output is the query shape and table/column names, not real request data.","description":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only. Stays low — pg_stat_statements fingerprints replace literals with `$1`/`$2`, so the output is the query shape and table/column names, not real request data.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","No locks held."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many query fingerprints to return.","validation":{"min":1,"max":200}},{"name":"min_calls","type":"integer","required":false,"default":10,"description":"Skip query fingerprints with fewer than N total calls (filters one-off DDL noise).","validation":{"min":1,"max":100000}}],"examples":[{"title":"Top 20 slow queries (default)","args":{}},{"title":"Top 50 with at least 100 calls","args":{"limit":50,"min_calls":100}}],"search_terms":["db is slow","database slow","slow db","query performance"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, round(mean_exec_time::numeric, 2) AS mean_ms, round(total_exec_time::numeric, 2) AS total_ms, left(query, 200) AS query FROM pg_stat_statements WHERE calls >= {{ args.min_calls }} ORDER BY mean_exec_time DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.ssl_connections","title":"pg_stat_ssl","summary":"List per-backend TLS state: version, cipher, client_serial.","description":"List per-backend TLS state: version, cipher, client_serial.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"TLS state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.pid, a.usename, a.application_name, s.ssl, s.version, s.cipher FROM pg_stat_ssl s JOIN pg_stat_activity a USING (pid) ORDER BY s.ssl DESC, s.pid LIMIT 100;"]}},{"id":"postgres.table_io","title":"pg_statio_user_tables","summary":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","description":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table IO","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, heap_blks_read, heap_blks_hit, ROUND(100.0 * heap_blks_hit / NULLIF(heap_blks_hit + heap_blks_read, 0), 2) AS heap_hit_pct, idx_blks_read, idx_blks_hit, ROUND(100.0 * idx_blks_hit / NULLIF(idx_blks_hit + idx_blks_read, 0), 2) AS idx_hit_pct FROM pg_statio_user_tables ORDER BY heap_blks_read + idx_blks_read DESC LIMIT 50;"]}},{"id":"postgres.table_sizes","title":"Top tables by total size","summary":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","description":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_class + pg_namespace.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"20 biggest tables in public","args":{}},{"title":"50 biggest tables in app schema","args":{"limit":50,"schema":"app"}}],"search_terms":["database out of space","db size","disk usage","largest tables"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname AS schema, c.relname AS table, pg_size_pretty(pg_total_relation_size(c.oid)) AS total, pg_size_pretty(pg_relation_size(c.oid)) AS heap, pg_size_pretty(pg_indexes_size(c.oid)) AS indexes FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname = '{{ args.schema }}' ORDER BY pg_total_relation_size(c.oid) DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.terminate_backend","title":"pg_terminate_backend(pid)","summary":"Hard-disconnect one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","description":"Hard-disconnect one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","kind":"exec","risk":"high","side_effects":["Targeted backend's connection is severed.","Open transactions roll back.","Held locks are released."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kill one backend","args":{"pid":12345}}],"search_terms":["kill connection","kill session","force disconnect"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_terminate_backend({{ args.pid }});"]}},{"id":"postgres.unused_indexes","title":"Unused indexes (idx_scan = 0)","summary":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","description":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Drop candidates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, i.indisunique, i.indisprimary FROM pg_stat_user_indexes s JOIN pg_index i ON i.indexrelid = s.indexrelid WHERE s.idx_scan = 0 AND NOT i.indisunique AND NOT i.indisprimary ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.uptime","title":"Postgres uptime and version","summary":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","description":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","kind":"exec","risk":"low","side_effects":["Issues two SELECTs against system catalogs.","No locks, no writes."],"args":[],"examples":[{"title":"Basic server uptime check","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT version(); SELECT pg_postmaster_start_time(); SELECT count(*) FROM pg_stat_activity;"]}},{"id":"postgres.vacuum_status","title":"Autovacuum + bloat snapshot","summary":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","description":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_user_tables.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Find tables with the most dead rows","args":{}}],"search_terms":["vacuum not running","table bloat"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname, relname, n_live_tup, n_dead_tup, round(100 * n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE schemaname = '{{ args.schema }}' ORDER BY n_dead_tup DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.vacuum_table","title":"VACUUM <schema>.<table>","summary":"Reclaim dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","description":"Reclaim dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","kind":"exec","risk":"high","side_effects":["IO-heavy proportional to table size.","DML continues during the vacuum.","Does NOT shrink the table file — for that, use VACUUM FULL (not exposed here; rebuilds the table with AccessExclusiveLock)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"analyze","type":"boolean","required":false,"default":true,"description":"Also run ANALYZE."}],"examples":[{"title":"VACUUM ANALYZE one table","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","VACUUM (VERBOSE, ANALYZE {{ args.analyze }}) {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.wal_archive_status","title":"pg_stat_archiver","summary":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","description":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Archiver","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_archiver;"]}},{"id":"postgres.wal_status","title":"Current WAL LSN + recovery state","summary":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","description":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"WAL state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery() AS in_recovery, CASE WHEN pg_is_in_recovery() THEN NULL ELSE pg_current_wal_lsn() END AS current_lsn, pg_last_wal_receive_lsn() AS last_receive_lsn, pg_last_wal_replay_lsn() AS last_replay_lsn, pg_last_xact_replay_timestamp() AS last_replay_time;"]}},{"id":"postgres.xid_wraparound_proximity","title":"How close are we to XID wraparound?","summary":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","description":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Wraparound risk","args":{}}],"search_terms":["transaction id wraparound","vacuum freeze age"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, age(datfrozenxid) AS xid_age, ROUND(100.0 * age(datfrozenxid) / 2147483648.0, 2) AS pct_to_wraparound FROM pg_database ORDER BY age(datfrozenxid) DESC;"]}}],"previous_versions":[{"version":"0.2.16","content_hash":"sha256:92af1d2014a25563219d8bff7bdda8d62b04bd7319fd43b6f7ea50f9a2459d23","tarball_url":"https://registry.emisar.dev/v1/packs/postgres/0.2.16/92af1d2014a25563219d8bff7bdda8d62b04bd7319fd43b6f7ea50f9a2459d23/pack.tar.gz","actions":[{"id":"postgres.activity_detail","title":"pg_stat_activity (per-backend)","summary":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text.","description":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks."],"args":[],"examples":[{"title":"All backends","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, state, wait_event_type, wait_event, EXTRACT(EPOCH FROM (now()-query_start))::int AS query_age_sec, EXTRACT(EPOCH FROM (now()-state_change))::int AS state_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 200;"]}},{"id":"postgres.activity_states","title":"Backend counts by state","summary":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","description":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"State counts","args":{}}],"search_terms":["too many connections","connection pileup"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, count(*) AS n FROM pg_stat_activity GROUP BY state ORDER BY n DESC;"]}},{"id":"postgres.analyze_table","title":"ANALYZE <schema>.<table>","summary":"Refresh planner statistics for one table.","description":"Refresh planner statistics for one table.","kind":"exec","risk":"medium","side_effects":["Reads sample rows from the table.","Updates pg_class/pg_statistic.","No locks beyond ShareUpdateExclusiveLock (DML continues)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Refresh stats","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","ANALYZE VERBOSE {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.backend_holding_xmin","title":"Backend holding the oldest xmin","summary":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide.","description":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum's enemy","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, state, backend_xmin, EXTRACT(EPOCH FROM (now()-xact_start))::int AS xact_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE backend_xmin IS NOT NULL ORDER BY backend_xmin::text::bigint ASC LIMIT 5;"]}},{"id":"postgres.bgwriter_stats","title":"pg_stat_bgwriter","summary":"Show background writer + checkpoint stats since stats reset.","description":"Show background writer + checkpoint stats since stats reset.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"bgwriter","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_bgwriter;"]}},{"id":"postgres.cancel_query","title":"Cancel a running query","summary":"Send SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","description":"Send SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","kind":"exec","risk":"high","side_effects":["The target backend's current query is cancelled with an ERROR.","The client connection stays open and the transaction is rolled back.","Does not affect other sessions."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID to cancel (see pg_stat_activity).","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Cancel backend 12345","args":{"pid":12345}}],"search_terms":["kill query","stop query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_cancel_backend({{ args.pid }});"]}},{"id":"postgres.connections","title":"Postgres connection summary","summary":"Count pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","description":"Count pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks held."],"args":[],"examples":[{"title":"Spot idle-in-transaction backends","args":{}}],"search_terms":["too many connections","connection pileup","max_connections","connection storm"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, application_name, count(*) AS n FROM pg_stat_activity GROUP BY state, application_name ORDER BY n DESC LIMIT 50;"]}},{"id":"postgres.database_stats","title":"pg_stat_database","summary":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","description":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Per-DB stats","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, xact_commit, xact_rollback, blks_read, blks_hit, ROUND(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS cache_hit_pct, tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted, deadlocks, conflicts, temp_files, pg_size_pretty(temp_bytes) AS temp_size FROM pg_stat_database WHERE datname IS NOT NULL ORDER BY (blks_read + blks_hit) DESC LIMIT 30;"]}},{"id":"postgres.db_sizes","title":"All databases by size","summary":"List every database with pg_database_size.","description":"List every database with pg_database_size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":["database out of space","db size","disk usage"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE NOT datistemplate ORDER BY pg_database_size(datname) DESC;"]}},{"id":"postgres.dead_tuples_top","title":"Top tables by dead-tuple ratio","summary":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","description":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Bloat suspects","args":{}}],"search_terms":["table bloat","autovacuum not keeping up"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_live_tup, n_dead_tup, ROUND(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE n_live_tup + n_dead_tup > 10000 ORDER BY n_dead_tup DESC LIMIT 30;"]}},{"id":"postgres.duplicate_indexes","title":"Duplicate indexes (same column set)","summary":"List indexes covering identical columns. One per group is redundant; drop after verifying.","description":"List indexes covering identical columns. One per group is redundant; drop after verifying.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Duplicates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT array_agg(indexrelid::regclass::text ORDER BY indexrelid) AS indexes, indrelid::regclass AS table, indkey::text AS columns FROM pg_index GROUP BY indrelid, indkey HAVING count(*) > 1 LIMIT 50;"]}},{"id":"postgres.explain_analyze","title":"EXPLAIN ANALYZE (FORMAT JSON) <query>","summary":"Run EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","description":"Run EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","kind":"exec","risk":"high","side_effects":["Query is executed with timing instrumentation, inside a read-only transaction.","Slower than EXPLAIN-only; a heavy query loads the server for up to the timeout.","Data-modifying statements and CTEs (INSERT/UPDATE/DELETE) are rejected by the read-only transaction."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT or WITH statement (executed read-only).","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Analyze count query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) {{ args.query }}"]}},{"id":"postgres.explain_query","title":"EXPLAIN (FORMAT JSON) <query>","summary":"Show the plan-only EXPLAIN. The query is NOT executed.","description":"Show the plan-only EXPLAIN. The query is NOT executed.","kind":"exec","risk":"low","side_effects":["Parses + plans the query.","Read-only — query body is not executed."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT statement.","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Plan one query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (FORMAT JSON, VERBOSE) {{ args.query }}"]}},{"id":"postgres.extensions_installed","title":"Installed extensions","summary":"List currently-loaded extensions with versions + schema.","description":"List currently-loaded extensions with versions + schema.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Extensions","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT extname, extversion, n.nspname AS schema FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace ORDER BY extname;"]}},{"id":"postgres.hot_update_ratio","title":"HOT update ratio per table","summary":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","description":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"HOT update ratios","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_tup_upd, n_tup_hot_upd, ROUND(100.0 * n_tup_hot_upd / NULLIF(n_tup_upd, 0), 2) AS hot_pct FROM pg_stat_user_tables WHERE n_tup_upd > 10000 ORDER BY n_tup_upd DESC LIMIT 30;"]}},{"id":"postgres.idle_in_transaction","title":"Idle-in-transaction backends","summary":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon.","description":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"IIT offenders","args":{}}],"search_terms":["stuck transaction","uncommitted transaction","connection leak"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, EXTRACT(EPOCH FROM (now()-state_change))::int AS idle_sec, substring(query, 1, 300) AS last_query FROM pg_stat_activity WHERE state IN ('idle in transaction','idle in transaction (aborted)') ORDER BY state_change ASC LIMIT 100;"]}},{"id":"postgres.index_sizes","title":"Top 50 indexes by size","summary":"List the largest indexes — candidates for bloat investigation.","description":"List the largest indexes — candidates for bloat investigation.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Largest indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, s.idx_scan FROM pg_stat_user_indexes s ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.invalid_indexes","title":"Invalid indexes (indisvalid = false)","summary":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","description":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Broken indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname || '.' || c.relname AS index, t.relname AS table, pg_size_pretty(pg_relation_size(c.oid)) AS size FROM pg_index i JOIN pg_class c ON c.oid = i.indexrelid JOIN pg_class t ON t.oid = i.indrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE NOT i.indisvalid;"]}},{"id":"postgres.is_in_recovery","title":"pg_is_in_recovery()","summary":"Show whether this instance is a replica (boolean — true if in recovery).","description":"Show whether this instance is a replica (boolean — true if in recovery).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recovery?","args":{}}],"search_terms":["primary or replica","is this the primary"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery();"]}},{"id":"postgres.kill_idle","title":"Terminate idle-in-transaction backends","summary":"Call `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","description":"Call `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","kind":"exec","risk":"high","side_effects":["SIGTERMs every matching backend.","In-flight transactions on those connections roll back.","Clients see a closed connection and must reconnect."],"args":[{"name":"older_than_seconds","type":"integer","required":false,"default":600,"description":"Only terminate idle-in-transaction backends older than this (default 10 min).","validation":{"min":60,"max":86400}}],"examples":[{"title":"Kill anything idle-in-transaction > 10 min","args":{}},{"title":"Aggressive — anything > 60 s","args":{"older_than_seconds":60}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND state_change < now() - interval '{{ args.older_than_seconds }} seconds';"]}},{"id":"postgres.largest_tables_full","title":"Largest tables with vacuum/dead-tuple info","summary":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","description":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_stat_user_tables.","Read-only."],"args":[],"examples":[{"title":"Top tables","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, pg_size_pretty(pg_total_relation_size(relid)) AS total_size, pg_size_pretty(pg_relation_size(relid)) AS table_size, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 50;"]}},{"id":"postgres.last_vacuum_per_table","title":"Last vacuum/analyze per table","summary":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","description":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum freshness","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, n_live_tup, n_dead_tup FROM pg_stat_user_tables ORDER BY COALESCE(last_autovacuum, last_vacuum) ASC NULLS FIRST LIMIT 50;"]}},{"id":"postgres.lock_blocking_chains","title":"Blocker → blocked chains","summary":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain.","description":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_locks.","Read-only."],"args":[],"examples":[{"title":"Lock chains","args":{}}],"search_terms":["lock contention","who is blocking","waiting on lock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocking.pid AS blocker_pid, blocked.usename AS blocked_user, blocking.usename AS blocker_user, blocked.wait_event_type, blocked.wait_event, substring(blocked.query, 1, 200) AS blocked_query, substring(blocking.query, 1, 200) AS blocker_query FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));"]}},{"id":"postgres.locks","title":"Blocking lock graph","summary":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim.","description":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_locks and pg_stat_activity.","No locks held by this query."],"args":[],"examples":[{"title":"What's currently blocked?","args":{}}],"search_terms":["lock contention","waiting on lock","deadlock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocked.usename AS blocked_user, left(blocked.query, 120) AS blocked_query, blocking.pid AS blocking_pid, blocking.usename AS blocking_user, left(blocking.query, 120) AS blocking_query, blocked.wait_event_type, blocked.wait_event FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid)) WHERE blocked.wait_event_type IS NOT NULL ORDER BY blocked.pid LIMIT 50;"]}},{"id":"postgres.longest_running_queries","title":"Top 20 by query age","summary":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work.","description":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Long-runners","args":{}}],"search_terms":["db is slow","database slow","slow db","long running query","stuck query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, EXTRACT(EPOCH FROM (now()-query_start))::int AS age_sec, wait_event_type, wait_event, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE state='active' AND pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 20;"]}},{"id":"postgres.pg_hba_rules","title":"pg_hba_file_rules","summary":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","description":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only — LDAP/RADIUS auth secrets are stripped from the options column."],"args":[],"examples":[{"title":"Hba rules","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT line_number, type, database, user_name, address, netmask, auth_method, array(SELECT o FROM unnest(options) AS o WHERE o NOT LIKE 'ldapbindpasswd=%' AND o NOT LIKE 'radiussecrets=%') AS options, error FROM pg_hba_file_rules ORDER BY line_number;"]}},{"id":"postgres.pg_stat_statements_reset","title":"pg_stat_statements_reset()","summary":"Clear accumulated pg_stat_statements counters. Use to start a clean measurement window.","description":"Clear accumulated pg_stat_statements counters. Use to start a clean measurement window.","kind":"exec","risk":"medium","side_effects":["All accumulated counters are reset to 0.","Future queries start from a clean baseline."],"args":[],"examples":[{"title":"Reset","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_stat_statements_reset();"]}},{"id":"postgres.pg_stat_statements_top","title":"Top statements by total time","summary":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded.","description":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","Read-only."],"args":[],"examples":[{"title":"Heavy hitters","args":{}}],"search_terms":["db is slow","database slow","slow db","expensive queries"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, ROUND(total_exec_time::numeric, 0) AS total_ms, ROUND(mean_exec_time::numeric, 1) AS mean_ms, rows, ROUND(100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0), 1) AS cache_hit_pct, substring(query, 1, 300) AS query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 30;"]}},{"id":"postgres.progress_create_index","title":"pg_stat_progress_create_index","summary":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","description":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live CREATE INDEXes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, p.index_relid::regclass AS index, phase, blocks_total, blocks_done, tuples_total, tuples_done FROM pg_stat_progress_create_index p;"]}},{"id":"postgres.progress_vacuum","title":"pg_stat_progress_vacuum","summary":"Show in-flight VACUUMs with phase + heap_blks_scanned.","description":"Show in-flight VACUUMs with phase + heap_blks_scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live VACUUMs","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, num_dead_tuples FROM pg_stat_progress_vacuum p;"]}},{"id":"postgres.reindex_concurrent","title":"REINDEX INDEX CONCURRENTLY <schema>.<index>","summary":"Rebuild one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","description":"Rebuild one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","kind":"exec","risk":"high","side_effects":["New copy of the index is built alongside.","Old index dropped at end; brief lock at swap.","On failure, an _ccnew suffix index may be left behind."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Rebuild bloated index","args":{"index":"orders_user_id_idx","schema":"public"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","REINDEX INDEX CONCURRENTLY {{ args.schema }}.{{ args.index }};"]}},{"id":"postgres.reload_conf","title":"Reload postgresql.conf","summary":"Call `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","description":"Call `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","kind":"exec","risk":"high","side_effects":["Server re-reads postgresql.conf and pg_hba.conf.","Active sessions keep their old settings until they reconnect for `user`-context settings; sighup-context settings apply immediately.","A malformed config logs a warning and keeps the previous values."],"args":[],"examples":[{"title":"Reload after editing postgresql.conf","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_reload_conf();"]}},{"id":"postgres.replication_lag","title":"Replication lag (primary view)","summary":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","description":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_replication.","No locks held."],"args":[],"examples":[{"title":"How far behind are my replicas?","args":{}}],"search_terms":["replica out of sync","replication behind","standby lag"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT application_name, client_addr, state, sync_state, pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) AS sent_lag, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag FROM pg_stat_replication ORDER BY application_name;"]}},{"id":"postgres.replication_slots","title":"pg_replication_slots","summary":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","description":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slots","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT slot_name, slot_type, plugin, database, active, restart_lsn, confirmed_flush_lsn, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;"]}},{"id":"postgres.seq_scan_offenders","title":"Tables with high seq-scan ratio","summary":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","description":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Seq scan offenders","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, seq_scan, idx_scan, seq_tup_read, idx_tup_fetch, ROUND(100.0 * seq_scan / NULLIF(seq_scan + idx_scan, 0), 2) AS seq_scan_pct, n_live_tup FROM pg_stat_user_tables WHERE seq_scan + idx_scan > 0 AND seq_tup_read > 100000 ORDER BY seq_tup_read DESC LIMIT 30;"]}},{"id":"postgres.settings_non_default","title":"pg_settings (non-default)","summary":"List settings the operator has changed from the compiled defaults.","description":"List settings the operator has changed from the compiled defaults.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Non-default settings","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT name, setting, unit, source, sourcefile, sourceline FROM pg_settings WHERE source NOT IN ('default', 'override') ORDER BY name;"]}},{"id":"postgres.slow_queries","title":"Top slow queries from pg_stat_statements","summary":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only.","description":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","No locks held."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many query fingerprints to return.","validation":{"min":1,"max":200}},{"name":"min_calls","type":"integer","required":false,"default":10,"description":"Skip query fingerprints with fewer than N total calls (filters one-off DDL noise).","validation":{"min":1,"max":100000}}],"examples":[{"title":"Top 20 slow queries (default)","args":{}},{"title":"Top 50 with at least 100 calls","args":{"limit":50,"min_calls":100}}],"search_terms":["db is slow","database slow","slow db","query performance"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, round(mean_exec_time::numeric, 2) AS mean_ms, round(total_exec_time::numeric, 2) AS total_ms, left(query, 200) AS query FROM pg_stat_statements WHERE calls >= {{ args.min_calls }} ORDER BY mean_exec_time DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.ssl_connections","title":"pg_stat_ssl","summary":"List per-backend TLS state: version, cipher, client_serial.","description":"List per-backend TLS state: version, cipher, client_serial.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"TLS state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.pid, a.usename, a.application_name, s.ssl, s.version, s.cipher FROM pg_stat_ssl s JOIN pg_stat_activity a USING (pid) ORDER BY s.ssl DESC, s.pid LIMIT 100;"]}},{"id":"postgres.table_io","title":"pg_statio_user_tables","summary":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","description":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table IO","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, heap_blks_read, heap_blks_hit, ROUND(100.0 * heap_blks_hit / NULLIF(heap_blks_hit + heap_blks_read, 0), 2) AS heap_hit_pct, idx_blks_read, idx_blks_hit, ROUND(100.0 * idx_blks_hit / NULLIF(idx_blks_hit + idx_blks_read, 0), 2) AS idx_hit_pct FROM pg_statio_user_tables ORDER BY heap_blks_read + idx_blks_read DESC LIMIT 50;"]}},{"id":"postgres.table_sizes","title":"Top tables by total size","summary":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","description":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_class + pg_namespace.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"20 biggest tables in public","args":{}},{"title":"50 biggest tables in app schema","args":{"limit":50,"schema":"app"}}],"search_terms":["database out of space","db size","disk usage","largest tables"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname AS schema, c.relname AS table, pg_size_pretty(pg_total_relation_size(c.oid)) AS total, pg_size_pretty(pg_relation_size(c.oid)) AS heap, pg_size_pretty(pg_indexes_size(c.oid)) AS indexes FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname = '{{ args.schema }}' ORDER BY pg_total_relation_size(c.oid) DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.terminate_backend","title":"pg_terminate_backend(pid)","summary":"Hard-disconnect one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","description":"Hard-disconnect one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","kind":"exec","risk":"high","side_effects":["Targeted backend's connection is severed.","Open transactions roll back.","Held locks are released."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kill one backend","args":{"pid":12345}}],"search_terms":["kill connection","kill session","force disconnect"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_terminate_backend({{ args.pid }});"]}},{"id":"postgres.unused_indexes","title":"Unused indexes (idx_scan = 0)","summary":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","description":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Drop candidates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, i.indisunique, i.indisprimary FROM pg_stat_user_indexes s JOIN pg_index i ON i.indexrelid = s.indexrelid WHERE s.idx_scan = 0 AND NOT i.indisunique AND NOT i.indisprimary ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.uptime","title":"Postgres uptime and version","summary":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","description":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","kind":"exec","risk":"low","side_effects":["Issues two SELECTs against system catalogs.","No locks, no writes."],"args":[],"examples":[{"title":"Basic server uptime check","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT version(); SELECT pg_postmaster_start_time(); SELECT count(*) FROM pg_stat_activity;"]}},{"id":"postgres.vacuum_status","title":"Autovacuum + bloat snapshot","summary":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","description":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_user_tables.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Find tables with the most dead rows","args":{}}],"search_terms":["vacuum not running","table bloat"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname, relname, n_live_tup, n_dead_tup, round(100 * n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE schemaname = '{{ args.schema }}' ORDER BY n_dead_tup DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.vacuum_table","title":"VACUUM <schema>.<table>","summary":"Reclaim dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","description":"Reclaim dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","kind":"exec","risk":"high","side_effects":["IO-heavy proportional to table size.","DML continues during the vacuum.","Does NOT shrink the table file — for that, use VACUUM FULL (not exposed here; rebuilds the table with AccessExclusiveLock)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"analyze","type":"boolean","required":false,"default":true,"description":"Also run ANALYZE."}],"examples":[{"title":"VACUUM ANALYZE one table","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","VACUUM (VERBOSE, ANALYZE {{ args.analyze }}) {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.wal_archive_status","title":"pg_stat_archiver","summary":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","description":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Archiver","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_archiver;"]}},{"id":"postgres.wal_status","title":"Current WAL LSN + recovery state","summary":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","description":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"WAL state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery() AS in_recovery, CASE WHEN pg_is_in_recovery() THEN NULL ELSE pg_current_wal_lsn() END AS current_lsn, pg_last_wal_receive_lsn() AS last_receive_lsn, pg_last_wal_replay_lsn() AS last_replay_lsn, pg_last_xact_replay_timestamp() AS last_replay_time;"]}},{"id":"postgres.xid_wraparound_proximity","title":"How close are we to XID wraparound?","summary":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","description":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Wraparound risk","args":{}}],"search_terms":["transaction id wraparound","vacuum freeze age"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, age(datfrozenxid) AS xid_age, ROUND(100.0 * age(datfrozenxid) / 2147483648.0, 2) AS pct_to_wraparound FROM pg_database ORDER BY age(datfrozenxid) DESC;"]}}]},{"version":"0.2.12","content_hash":"sha256:bd617c1e5c412be4cd4959de486ed9e1f08ef16e469f0aa7738bc690bb2ad007","tarball_url":"https://registry.emisar.dev/v1/packs/postgres/0.2.12/bd617c1e5c412be4cd4959de486ed9e1f08ef16e469f0aa7738bc690bb2ad007/pack.tar.gz","actions":[{"id":"postgres.activity_detail","title":"pg_stat_activity (per-backend)","summary":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text.","description":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks."],"args":[],"examples":[{"title":"All backends","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, state, wait_event_type, wait_event, EXTRACT(EPOCH FROM (now()-query_start))::int AS query_age_sec, EXTRACT(EPOCH FROM (now()-state_change))::int AS state_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 200;"]}},{"id":"postgres.activity_states","title":"Backend counts by state","summary":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","description":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"State counts","args":{}}],"search_terms":["too many connections","connection pileup"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, count(*) AS n FROM pg_stat_activity GROUP BY state ORDER BY n DESC;"]}},{"id":"postgres.analyze_table","title":"ANALYZE <schema>.<table>","summary":"Refresh planner statistics for one table.","description":"Refresh planner statistics for one table.","kind":"exec","risk":"medium","side_effects":["Reads sample rows from the table.","Updates pg_class/pg_statistic.","No locks beyond ShareUpdateExclusiveLock (DML continues)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Refresh stats","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","ANALYZE VERBOSE {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.backend_holding_xmin","title":"Backend holding the oldest xmin","summary":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide.","description":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum's enemy","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, state, backend_xmin, EXTRACT(EPOCH FROM (now()-xact_start))::int AS xact_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE backend_xmin IS NOT NULL ORDER BY backend_xmin::text::bigint ASC LIMIT 5;"]}},{"id":"postgres.bgwriter_stats","title":"pg_stat_bgwriter","summary":"Show background writer + checkpoint stats since stats reset.","description":"Show background writer + checkpoint stats since stats reset.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"bgwriter","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_bgwriter;"]}},{"id":"postgres.cancel_query","title":"Cancel a running query","summary":"Send SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","description":"Send SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","kind":"exec","risk":"high","side_effects":["The target backend's current query is cancelled with an ERROR.","The client connection stays open and the transaction is rolled back.","Does not affect other sessions."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID to cancel (see pg_stat_activity).","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Cancel backend 12345","args":{"pid":12345}}],"search_terms":["kill query","stop query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_cancel_backend({{ args.pid }});"]}},{"id":"postgres.connections","title":"Postgres connection summary","summary":"Count pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","description":"Count pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks held."],"args":[],"examples":[{"title":"Spot idle-in-transaction backends","args":{}}],"search_terms":["too many connections","connection pileup","max_connections","connection storm"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, application_name, count(*) AS n FROM pg_stat_activity GROUP BY state, application_name ORDER BY n DESC LIMIT 50;"]}},{"id":"postgres.database_stats","title":"pg_stat_database","summary":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","description":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Per-DB stats","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, xact_commit, xact_rollback, blks_read, blks_hit, ROUND(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS cache_hit_pct, tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted, deadlocks, conflicts, temp_files, pg_size_pretty(temp_bytes) AS temp_size FROM pg_stat_database WHERE datname IS NOT NULL ORDER BY (blks_read + blks_hit) DESC LIMIT 30;"]}},{"id":"postgres.db_sizes","title":"All databases by size","summary":"List every database with pg_database_size.","description":"List every database with pg_database_size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":["database out of space","db size","disk usage"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE NOT datistemplate ORDER BY pg_database_size(datname) DESC;"]}},{"id":"postgres.dead_tuples_top","title":"Top tables by dead-tuple ratio","summary":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","description":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Bloat suspects","args":{}}],"search_terms":["table bloat","autovacuum not keeping up"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_live_tup, n_dead_tup, ROUND(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE n_live_tup + n_dead_tup > 10000 ORDER BY n_dead_tup DESC LIMIT 30;"]}},{"id":"postgres.duplicate_indexes","title":"Duplicate indexes (same column set)","summary":"List indexes covering identical columns. One per group is redundant; drop after verifying.","description":"List indexes covering identical columns. One per group is redundant; drop after verifying.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Duplicates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT array_agg(indexrelid::regclass::text ORDER BY indexrelid) AS indexes, indrelid::regclass AS table, indkey::text AS columns FROM pg_index GROUP BY indrelid, indkey HAVING count(*) > 1 LIMIT 50;"]}},{"id":"postgres.explain_analyze","title":"EXPLAIN ANALYZE (FORMAT JSON) <query>","summary":"Run EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","description":"Run EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","kind":"exec","risk":"high","side_effects":["Query is executed with timing instrumentation, inside a read-only transaction.","Slower than EXPLAIN-only; a heavy query loads the server for up to the timeout.","Data-modifying statements and CTEs (INSERT/UPDATE/DELETE) are rejected by the read-only transaction."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT or WITH statement (executed read-only).","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Analyze count query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) {{ args.query }}"]}},{"id":"postgres.explain_query","title":"EXPLAIN (FORMAT JSON) <query>","summary":"Show the plan-only EXPLAIN. The query is NOT executed.","description":"Show the plan-only EXPLAIN. The query is NOT executed.","kind":"exec","risk":"low","side_effects":["Parses + plans the query.","Read-only — query body is not executed."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT statement.","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Plan one query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (FORMAT JSON, VERBOSE) {{ args.query }}"]}},{"id":"postgres.extensions_installed","title":"Installed extensions","summary":"List currently-loaded extensions with versions + schema.","description":"List currently-loaded extensions with versions + schema.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Extensions","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT extname, extversion, n.nspname AS schema FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace ORDER BY extname;"]}},{"id":"postgres.hot_update_ratio","title":"HOT update ratio per table","summary":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","description":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"HOT update ratios","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_tup_upd, n_tup_hot_upd, ROUND(100.0 * n_tup_hot_upd / NULLIF(n_tup_upd, 0), 2) AS hot_pct FROM pg_stat_user_tables WHERE n_tup_upd > 10000 ORDER BY n_tup_upd DESC LIMIT 30;"]}},{"id":"postgres.idle_in_transaction","title":"Idle-in-transaction backends","summary":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon.","description":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"IIT offenders","args":{}}],"search_terms":["stuck transaction","uncommitted transaction","connection leak"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, EXTRACT(EPOCH FROM (now()-state_change))::int AS idle_sec, substring(query, 1, 300) AS last_query FROM pg_stat_activity WHERE state IN ('idle in transaction','idle in transaction (aborted)') ORDER BY state_change ASC LIMIT 100;"]}},{"id":"postgres.index_sizes","title":"Top 50 indexes by size","summary":"List the largest indexes — candidates for bloat investigation.","description":"List the largest indexes — candidates for bloat investigation.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Largest indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, s.idx_scan FROM pg_stat_user_indexes s ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.invalid_indexes","title":"Invalid indexes (indisvalid = false)","summary":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","description":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Broken indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname || '.' || c.relname AS index, t.relname AS table, pg_size_pretty(pg_relation_size(c.oid)) AS size FROM pg_index i JOIN pg_class c ON c.oid = i.indexrelid JOIN pg_class t ON t.oid = i.indrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE NOT i.indisvalid;"]}},{"id":"postgres.is_in_recovery","title":"pg_is_in_recovery()","summary":"Show whether this instance is a replica (boolean — true if in recovery).","description":"Show whether this instance is a replica (boolean — true if in recovery).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recovery?","args":{}}],"search_terms":["primary or replica","is this the primary"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery();"]}},{"id":"postgres.kill_idle","title":"Terminate idle-in-transaction backends","summary":"Call `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","description":"Call `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","kind":"exec","risk":"high","side_effects":["SIGTERMs every matching backend.","In-flight transactions on those connections roll back.","Clients see a closed connection and must reconnect."],"args":[{"name":"older_than_seconds","type":"integer","required":false,"default":600,"description":"Only terminate idle-in-transaction backends older than this (default 10 min).","validation":{"min":60,"max":86400}}],"examples":[{"title":"Kill anything idle-in-transaction > 10 min","args":{}},{"title":"Aggressive — anything > 60 s","args":{"older_than_seconds":60}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND state_change < now() - interval '{{ args.older_than_seconds }} seconds';"]}},{"id":"postgres.largest_tables_full","title":"Largest tables with vacuum/dead-tuple info","summary":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","description":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_stat_user_tables.","Read-only."],"args":[],"examples":[{"title":"Top tables","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, pg_size_pretty(pg_total_relation_size(relid)) AS total_size, pg_size_pretty(pg_relation_size(relid)) AS table_size, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 50;"]}},{"id":"postgres.last_vacuum_per_table","title":"Last vacuum/analyze per table","summary":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","description":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum freshness","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, n_live_tup, n_dead_tup FROM pg_stat_user_tables ORDER BY COALESCE(last_autovacuum, last_vacuum) ASC NULLS FIRST LIMIT 50;"]}},{"id":"postgres.lock_blocking_chains","title":"Blocker → blocked chains","summary":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain.","description":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_locks.","Read-only."],"args":[],"examples":[{"title":"Lock chains","args":{}}],"search_terms":["lock contention","who is blocking","waiting on lock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocking.pid AS blocker_pid, blocked.usename AS blocked_user, blocking.usename AS blocker_user, blocked.wait_event_type, blocked.wait_event, substring(blocked.query, 1, 200) AS blocked_query, substring(blocking.query, 1, 200) AS blocker_query FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));"]}},{"id":"postgres.locks","title":"Blocking lock graph","summary":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim.","description":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_locks and pg_stat_activity.","No locks held by this query."],"args":[],"examples":[{"title":"What's currently blocked?","args":{}}],"search_terms":["lock contention","waiting on lock","deadlock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocked.usename AS blocked_user, left(blocked.query, 120) AS blocked_query, blocking.pid AS blocking_pid, blocking.usename AS blocking_user, left(blocking.query, 120) AS blocking_query, blocked.wait_event_type, blocked.wait_event FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid)) WHERE blocked.wait_event_type IS NOT NULL ORDER BY blocked.pid LIMIT 50;"]}},{"id":"postgres.longest_running_queries","title":"Top 20 by query age","summary":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work.","description":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Long-runners","args":{}}],"search_terms":["db is slow","database slow","slow db","long running query","stuck query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, EXTRACT(EPOCH FROM (now()-query_start))::int AS age_sec, wait_event_type, wait_event, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE state='active' AND pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 20;"]}},{"id":"postgres.pg_hba_rules","title":"pg_hba_file_rules","summary":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","description":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only — LDAP/RADIUS auth secrets are stripped from the options column."],"args":[],"examples":[{"title":"Hba rules","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT line_number, type, database, user_name, address, netmask, auth_method, array(SELECT o FROM unnest(options) AS o WHERE o NOT LIKE 'ldapbindpasswd=%' AND o NOT LIKE 'radiussecrets=%') AS options, error FROM pg_hba_file_rules ORDER BY line_number;"]}},{"id":"postgres.pg_stat_statements_reset","title":"pg_stat_statements_reset()","summary":"Clear accumulated pg_stat_statements counters. Use to start a clean measurement window.","description":"Clear accumulated pg_stat_statements counters. Use to start a clean measurement window.","kind":"exec","risk":"medium","side_effects":["All accumulated counters are reset to 0.","Future queries start from a clean baseline."],"args":[],"examples":[{"title":"Reset","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_stat_statements_reset();"]}},{"id":"postgres.pg_stat_statements_top","title":"Top statements by total time","summary":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded.","description":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","Read-only."],"args":[],"examples":[{"title":"Heavy hitters","args":{}}],"search_terms":["db is slow","database slow","slow db","expensive queries"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, ROUND(total_exec_time::numeric, 0) AS total_ms, ROUND(mean_exec_time::numeric, 1) AS mean_ms, rows, ROUND(100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0), 1) AS cache_hit_pct, substring(query, 1, 300) AS query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 30;"]}},{"id":"postgres.progress_create_index","title":"pg_stat_progress_create_index","summary":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","description":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live CREATE INDEXes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, p.index_relid::regclass AS index, phase, blocks_total, blocks_done, tuples_total, tuples_done FROM pg_stat_progress_create_index p;"]}},{"id":"postgres.progress_vacuum","title":"pg_stat_progress_vacuum","summary":"Show in-flight VACUUMs with phase + heap_blks_scanned.","description":"Show in-flight VACUUMs with phase + heap_blks_scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live VACUUMs","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, num_dead_tuples FROM pg_stat_progress_vacuum p;"]}},{"id":"postgres.reindex_concurrent","title":"REINDEX INDEX CONCURRENTLY <schema>.<index>","summary":"Rebuild one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","description":"Rebuild one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","kind":"exec","risk":"high","side_effects":["New copy of the index is built alongside.","Old index dropped at end; brief lock at swap.","On failure, an _ccnew suffix index may be left behind."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Rebuild bloated index","args":{"index":"orders_user_id_idx","schema":"public"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","REINDEX INDEX CONCURRENTLY {{ args.schema }}.{{ args.index }};"]}},{"id":"postgres.reload_conf","title":"Reload postgresql.conf","summary":"Call `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","description":"Call `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","kind":"exec","risk":"high","side_effects":["Server re-reads postgresql.conf and pg_hba.conf.","Active sessions keep their old settings until they reconnect for `user`-context settings; sighup-context settings apply immediately.","A malformed config logs a warning and keeps the previous values."],"args":[],"examples":[{"title":"Reload after editing postgresql.conf","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_reload_conf();"]}},{"id":"postgres.replication_lag","title":"Replication lag (primary view)","summary":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","description":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_replication.","No locks held."],"args":[],"examples":[{"title":"How far behind are my replicas?","args":{}}],"search_terms":["replica out of sync","replication behind","standby lag"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT application_name, client_addr, state, sync_state, pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) AS sent_lag, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag FROM pg_stat_replication ORDER BY application_name;"]}},{"id":"postgres.replication_slots","title":"pg_replication_slots","summary":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","description":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slots","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT slot_name, slot_type, plugin, database, active, restart_lsn, confirmed_flush_lsn, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;"]}},{"id":"postgres.seq_scan_offenders","title":"Tables with high seq-scan ratio","summary":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","description":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Seq scan offenders","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, seq_scan, idx_scan, seq_tup_read, idx_tup_fetch, ROUND(100.0 * seq_scan / NULLIF(seq_scan + idx_scan, 0), 2) AS seq_scan_pct, n_live_tup FROM pg_stat_user_tables WHERE seq_scan + idx_scan > 0 AND seq_tup_read > 100000 ORDER BY seq_tup_read DESC LIMIT 30;"]}},{"id":"postgres.settings_non_default","title":"pg_settings (non-default)","summary":"List settings the operator has changed from the compiled defaults.","description":"List settings the operator has changed from the compiled defaults.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Non-default settings","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT name, setting, unit, source, sourcefile, sourceline FROM pg_settings WHERE source NOT IN ('default', 'override') ORDER BY name;"]}},{"id":"postgres.slow_queries","title":"Top slow queries from pg_stat_statements","summary":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only.","description":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","No locks held."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many query fingerprints to return.","validation":{"min":1,"max":200}},{"name":"min_calls","type":"integer","required":false,"default":10,"description":"Skip query fingerprints with fewer than N total calls (filters one-off DDL noise).","validation":{"min":1,"max":100000}}],"examples":[{"title":"Top 20 slow queries (default)","args":{}},{"title":"Top 50 with at least 100 calls","args":{"limit":50,"min_calls":100}}],"search_terms":["db is slow","database slow","slow db","query performance"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, round(mean_exec_time::numeric, 2) AS mean_ms, round(total_exec_time::numeric, 2) AS total_ms, left(query, 200) AS query FROM pg_stat_statements WHERE calls >= {{ args.min_calls }} ORDER BY mean_exec_time DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.ssl_connections","title":"pg_stat_ssl","summary":"List per-backend TLS state: version, cipher, client_serial.","description":"List per-backend TLS state: version, cipher, client_serial.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"TLS state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.pid, a.usename, a.application_name, s.ssl, s.version, s.cipher FROM pg_stat_ssl s JOIN pg_stat_activity a USING (pid) ORDER BY s.ssl DESC, s.pid LIMIT 100;"]}},{"id":"postgres.table_io","title":"pg_statio_user_tables","summary":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","description":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table IO","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, heap_blks_read, heap_blks_hit, ROUND(100.0 * heap_blks_hit / NULLIF(heap_blks_hit + heap_blks_read, 0), 2) AS heap_hit_pct, idx_blks_read, idx_blks_hit, ROUND(100.0 * idx_blks_hit / NULLIF(idx_blks_hit + idx_blks_read, 0), 2) AS idx_hit_pct FROM pg_statio_user_tables ORDER BY heap_blks_read + idx_blks_read DESC LIMIT 50;"]}},{"id":"postgres.table_sizes","title":"Top tables by total size","summary":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","description":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_class + pg_namespace.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"20 biggest tables in public","args":{}},{"title":"50 biggest tables in app schema","args":{"limit":50,"schema":"app"}}],"search_terms":["database out of space","db size","disk usage","largest tables"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname AS schema, c.relname AS table, pg_size_pretty(pg_total_relation_size(c.oid)) AS total, pg_size_pretty(pg_relation_size(c.oid)) AS heap, pg_size_pretty(pg_indexes_size(c.oid)) AS indexes FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname = '{{ args.schema }}' ORDER BY pg_total_relation_size(c.oid) DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.terminate_backend","title":"pg_terminate_backend(pid)","summary":"Hard-disconnect one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","description":"Hard-disconnect one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","kind":"exec","risk":"high","side_effects":["Targeted backend's connection is severed.","Open transactions roll back.","Held locks are released."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kill one backend","args":{"pid":12345}}],"search_terms":["kill connection","kill session","force disconnect"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_terminate_backend({{ args.pid }});"]}},{"id":"postgres.unused_indexes","title":"Unused indexes (idx_scan = 0)","summary":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","description":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Drop candidates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, i.indisunique, i.indisprimary FROM pg_stat_user_indexes s JOIN pg_index i ON i.indexrelid = s.indexrelid WHERE s.idx_scan = 0 AND NOT i.indisunique AND NOT i.indisprimary ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.uptime","title":"Postgres uptime and version","summary":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","description":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","kind":"exec","risk":"low","side_effects":["Issues two SELECTs against system catalogs.","No locks, no writes."],"args":[],"examples":[{"title":"Basic server uptime check","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT version(); SELECT pg_postmaster_start_time(); SELECT count(*) FROM pg_stat_activity;"]}},{"id":"postgres.vacuum_status","title":"Autovacuum + bloat snapshot","summary":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","description":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_user_tables.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Find tables with the most dead rows","args":{}}],"search_terms":["vacuum not running","table bloat"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname, relname, n_live_tup, n_dead_tup, round(100 * n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE schemaname = '{{ args.schema }}' ORDER BY n_dead_tup DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.vacuum_table","title":"VACUUM <schema>.<table>","summary":"Reclaim dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","description":"Reclaim dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","kind":"exec","risk":"high","side_effects":["IO-heavy proportional to table size.","DML continues during the vacuum.","Does NOT shrink the table file — for that, use VACUUM FULL (not exposed here; rebuilds the table with AccessExclusiveLock)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"analyze","type":"boolean","required":false,"default":true,"description":"Also run ANALYZE."}],"examples":[{"title":"VACUUM ANALYZE one table","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","VACUUM (VERBOSE, ANALYZE {{ args.analyze }}) {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.wal_archive_status","title":"pg_stat_archiver","summary":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","description":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Archiver","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_archiver;"]}},{"id":"postgres.wal_status","title":"Current WAL LSN + recovery state","summary":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","description":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"WAL state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery() AS in_recovery, CASE WHEN pg_is_in_recovery() THEN NULL ELSE pg_current_wal_lsn() END AS current_lsn, pg_last_wal_receive_lsn() AS last_receive_lsn, pg_last_wal_replay_lsn() AS last_replay_lsn, pg_last_xact_replay_timestamp() AS last_replay_time;"]}},{"id":"postgres.xid_wraparound_proximity","title":"How close are we to XID wraparound?","summary":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","description":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Wraparound risk","args":{}}],"search_terms":["transaction id wraparound","vacuum freeze age"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, age(datfrozenxid) AS xid_age, ROUND(100.0 * age(datfrozenxid) / 2147483648.0, 2) AS pct_to_wraparound FROM pg_database ORDER BY age(datfrozenxid) DESC;"]}}]},{"version":"0.2.11","content_hash":"sha256:ec6f761fd7d750536bab793c92ec91bcf75a24c78c7ee00c4aeca5a057692f2c","tarball_url":"https://registry.emisar.dev/v1/packs/postgres/0.2.11/ec6f761fd7d750536bab793c92ec91bcf75a24c78c7ee00c4aeca5a057692f2c/pack.tar.gz","actions":[{"id":"postgres.activity_detail","title":"pg_stat_activity (per-backend)","summary":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text.","description":"Show per-backend detail: pid, user, app, state, wait_event, query age, query text.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks."],"args":[],"examples":[{"title":"All backends","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, state, wait_event_type, wait_event, EXTRACT(EPOCH FROM (now()-query_start))::int AS query_age_sec, EXTRACT(EPOCH FROM (now()-state_change))::int AS state_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 200;"]}},{"id":"postgres.activity_states","title":"Backend counts by state","summary":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","description":"Show a quick \"how many idle / active / idle-in-transaction\" health snapshot.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"State counts","args":{}}],"search_terms":["too many connections","connection pileup"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, count(*) AS n FROM pg_stat_activity GROUP BY state ORDER BY n DESC;"]}},{"id":"postgres.analyze_table","title":"ANALYZE <schema>.<table>","summary":"Refreshes planner statistics for one table.","description":"Refreshes planner statistics for one table.","kind":"exec","risk":"medium","side_effects":["Reads sample rows from the table.","Updates pg_class/pg_statistic.","No locks beyond ShareUpdateExclusiveLock (DML continues)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Refresh stats","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","ANALYZE VERBOSE {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.backend_holding_xmin","title":"Backend holding the oldest xmin","summary":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide.","description":"Show the backend whose snapshot is preventing vacuum from cleaning dead tuples cluster-wide.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum's enemy","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, state, backend_xmin, EXTRACT(EPOCH FROM (now()-xact_start))::int AS xact_age_sec, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE backend_xmin IS NOT NULL ORDER BY backend_xmin::text::bigint ASC LIMIT 5;"]}},{"id":"postgres.bgwriter_stats","title":"pg_stat_bgwriter","summary":"Show background writer + checkpoint stats since stats reset.","description":"Show background writer + checkpoint stats since stats reset.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"bgwriter","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_bgwriter;"]}},{"id":"postgres.cancel_query","title":"Cancel a running query","summary":"Sends SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","description":"Sends SIGINT to one backend via `pg_cancel_backend(pid)`. The query aborts but the connection survives. Use to clear a stuck SELECT or a blocker surfaced by `postgres.locks`. If cancel doesn't take effect within seconds the backend is likely stuck in a kernel call — escalate to `kill_idle` (terminate) only as a last resort.","kind":"exec","risk":"high","side_effects":["The target backend's current query is cancelled with an ERROR.","The client connection stays open and the transaction is rolled back.","Does not affect other sessions."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID to cancel (see pg_stat_activity).","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Cancel backend 12345","args":{"pid":12345}}],"search_terms":["kill query","stop query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_cancel_backend({{ args.pid }});"]}},{"id":"postgres.connections","title":"Postgres connection summary","summary":"Counts pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","description":"Counts pg_stat_activity rows grouped by state and application_name. Surfaces idle-in-transaction backends, connection storms, and per-app traffic skew. Read-only. Pair with `postgres.kill_idle` if the long-idle-in-transaction count is non-zero.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_activity.","No locks held."],"args":[],"examples":[{"title":"Spot idle-in-transaction backends","args":{}}],"search_terms":["too many connections","connection pileup","max_connections","connection storm"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT state, application_name, count(*) AS n FROM pg_stat_activity GROUP BY state, application_name ORDER BY n DESC LIMIT 50;"]}},{"id":"postgres.database_stats","title":"pg_stat_database","summary":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","description":"Show per-DB: commits/rollbacks, blks_read/hit, deadlocks, conflicts, temp file usage.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Per-DB stats","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, xact_commit, xact_rollback, blks_read, blks_hit, ROUND(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS cache_hit_pct, tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted, deadlocks, conflicts, temp_files, pg_size_pretty(temp_bytes) AS temp_size FROM pg_stat_database WHERE datname IS NOT NULL ORDER BY (blks_read + blks_hit) DESC LIMIT 30;"]}},{"id":"postgres.db_sizes","title":"All databases by size","summary":"List every database with pg_database_size.","description":"List every database with pg_database_size.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"All databases","args":{}}],"search_terms":["database out of space","db size","disk usage"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE NOT datistemplate ORDER BY pg_database_size(datname) DESC;"]}},{"id":"postgres.dead_tuples_top","title":"Top tables by dead-tuple ratio","summary":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","description":"List tables where n_dead_tup / (n_live_tup + n_dead_tup) is high. Bloat suspects.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Bloat suspects","args":{}}],"search_terms":["table bloat","autovacuum not keeping up"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_live_tup, n_dead_tup, ROUND(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE n_live_tup + n_dead_tup > 10000 ORDER BY n_dead_tup DESC LIMIT 30;"]}},{"id":"postgres.duplicate_indexes","title":"Duplicate indexes (same column set)","summary":"List indexes covering identical columns. One per group is redundant; drop after verifying.","description":"List indexes covering identical columns. One per group is redundant; drop after verifying.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Duplicates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT array_agg(indexrelid::regclass::text ORDER BY indexrelid) AS indexes, indrelid::regclass AS table, indkey::text AS columns FROM pg_index GROUP BY indrelid, indkey HAVING count(*) > 1 LIMIT 50;"]}},{"id":"postgres.explain_analyze","title":"EXPLAIN ANALYZE (FORMAT JSON) <query>","summary":"Runs EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","description":"Runs EXPLAIN ANALYZE — the query IS executed (with timing). Forced into a read-only transaction (default_transaction_read_only=on) so data-modifying CTEs and volatile writes are rejected by the server, but the read still runs and can be expensive. High-risk because it executes an arbitrary operator-supplied query on the live database; use explain_query for a plan without execution.","kind":"exec","risk":"high","side_effects":["Query is executed with timing instrumentation, inside a read-only transaction.","Slower than EXPLAIN-only; a heavy query loads the server for up to the timeout.","Data-modifying statements and CTEs (INSERT/UPDATE/DELETE) are rejected by the read-only transaction."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT or WITH statement (executed read-only).","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Analyze count query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) {{ args.query }}"]}},{"id":"postgres.explain_query","title":"EXPLAIN (FORMAT JSON) <query>","summary":"Show the plan-only EXPLAIN. The query is NOT executed.","description":"Show the plan-only EXPLAIN. The query is NOT executed.","kind":"exec","risk":"low","side_effects":["Parses + plans the query.","Read-only — query body is not executed."],"args":[{"name":"query","type":"string","required":true,"description":"SELECT statement.","validation":{"pattern":"^(SELECT|select|WITH|with)[^;]{1,1000}$"}}],"examples":[{"title":"Plan one query","args":{"query":"SELECT count(*) FROM pg_stat_activity"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","EXPLAIN (FORMAT JSON, VERBOSE) {{ args.query }}"]}},{"id":"postgres.extensions_installed","title":"Installed extensions","summary":"List currently-loaded extensions with versions + schema.","description":"List currently-loaded extensions with versions + schema.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Extensions","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT extname, extversion, n.nspname AS schema FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace ORDER BY extname;"]}},{"id":"postgres.hot_update_ratio","title":"HOT update ratio per table","summary":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","description":"Show HOT update ratio per table. HOT updates avoid index work and bloat. Low ratio on a hot table = missing fillfactor tuning or wrong index.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"HOT update ratios","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, n_tup_upd, n_tup_hot_upd, ROUND(100.0 * n_tup_hot_upd / NULLIF(n_tup_upd, 0), 2) AS hot_pct FROM pg_stat_user_tables WHERE n_tup_upd > 10000 ORDER BY n_tup_upd DESC LIMIT 30;"]}},{"id":"postgres.idle_in_transaction","title":"Idle-in-transaction backends","summary":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon.","description":"List backends sitting in 'idle in transaction' state — they hold locks + bloat vacuum's xmin horizon.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"IIT offenders","args":{}}],"search_terms":["stuck transaction","uncommitted transaction","connection leak"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, client_addr, EXTRACT(EPOCH FROM (now()-state_change))::int AS idle_sec, substring(query, 1, 300) AS last_query FROM pg_stat_activity WHERE state IN ('idle in transaction','idle in transaction (aborted)') ORDER BY state_change ASC LIMIT 100;"]}},{"id":"postgres.index_sizes","title":"Top 50 indexes by size","summary":"List the largest indexes — candidates for bloat investigation.","description":"List the largest indexes — candidates for bloat investigation.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Largest indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, s.idx_scan FROM pg_stat_user_indexes s ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.invalid_indexes","title":"Invalid indexes (indisvalid = false)","summary":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","description":"List indexes from failed CREATE INDEX CONCURRENTLY — present but not used by the planner.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Broken indexes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname || '.' || c.relname AS index, t.relname AS table, pg_size_pretty(pg_relation_size(c.oid)) AS size FROM pg_index i JOIN pg_class c ON c.oid = i.indexrelid JOIN pg_class t ON t.oid = i.indrelid JOIN pg_namespace n ON n.oid = c.relnamespace WHERE NOT i.indisvalid;"]}},{"id":"postgres.is_in_recovery","title":"pg_is_in_recovery()","summary":"Show whether this instance is a replica (boolean — true if in recovery).","description":"Show whether this instance is a replica (boolean — true if in recovery).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Recovery?","args":{}}],"search_terms":["primary or replica","is this the primary"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery();"]}},{"id":"postgres.kill_idle","title":"Terminate idle-in-transaction backends","summary":"Calls `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","description":"Calls `pg_terminate_backend(pid)` on every backend that has been in `idle in transaction` state longer than `older_than_seconds`. Frees up the locks they're holding. Application code on the killed connections will see \"server closed the connection unexpectedly\" and reconnect — any in-flight transaction rolls back. Always check the count via `postgres.connections` first. Do not run during normal traffic.","kind":"exec","risk":"high","side_effects":["SIGTERMs every matching backend.","In-flight transactions on those connections roll back.","Clients see a closed connection and must reconnect."],"args":[{"name":"older_than_seconds","type":"integer","required":false,"default":600,"description":"Only terminate idle-in-transaction backends older than this (default 10 min).","validation":{"min":60,"max":86400}}],"examples":[{"title":"Kill anything idle-in-transaction > 10 min","args":{}},{"title":"Aggressive — anything > 60 s","args":{"older_than_seconds":60}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND state_change < now() - interval '{{ args.older_than_seconds }} seconds';"]}},{"id":"postgres.largest_tables_full","title":"Largest tables with vacuum/dead-tuple info","summary":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","description":"List top 50 tables by size with live + dead tuple counts and last vacuum timestamps.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_stat_user_tables.","Read-only."],"args":[],"examples":[{"title":"Top tables","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, pg_size_pretty(pg_total_relation_size(relid)) AS total_size, pg_size_pretty(pg_relation_size(relid)) AS table_size, n_live_tup, n_dead_tup, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze FROM pg_stat_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 50;"]}},{"id":"postgres.last_vacuum_per_table","title":"Last vacuum/analyze per table","summary":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","description":"List tables ordered by oldest last-vacuum — find ones autovacuum hasn't touched.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Vacuum freshness","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze, n_live_tup, n_dead_tup FROM pg_stat_user_tables ORDER BY COALESCE(last_autovacuum, last_vacuum) ASC NULLS FIRST LIMIT 50;"]}},{"id":"postgres.lock_blocking_chains","title":"Blocker → blocked chains","summary":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain.","description":"List each blocked backend with its blocker. Use to find the head of a stuck lock chain.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_locks.","Read-only."],"args":[],"examples":[{"title":"Lock chains","args":{}}],"search_terms":["lock contention","who is blocking","waiting on lock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocking.pid AS blocker_pid, blocked.usename AS blocked_user, blocking.usename AS blocker_user, blocked.wait_event_type, blocked.wait_event, substring(blocked.query, 1, 200) AS blocked_query, substring(blocking.query, 1, 200) AS blocker_query FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));"]}},{"id":"postgres.locks","title":"Blocking lock graph","summary":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim.","description":"Show who's blocking whom. Joins pg_locks with pg_stat_activity to show blocker_pid → blocked_pid pairs plus the truncated SQL of each side. Read-only. Use before a `cancel_query`; you want to cancel the blocker, not the victim.","kind":"exec","risk":"low","side_effects":["One SELECT joining pg_locks and pg_stat_activity.","No locks held by this query."],"args":[],"examples":[{"title":"What's currently blocked?","args":{}}],"search_terms":["lock contention","waiting on lock","deadlock"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT blocked.pid AS blocked_pid, blocked.usename AS blocked_user, left(blocked.query, 120) AS blocked_query, blocking.pid AS blocking_pid, blocking.usename AS blocking_user, left(blocking.query, 120) AS blocking_query, blocked.wait_event_type, blocked.wait_event FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid)) WHERE blocked.wait_event_type IS NOT NULL ORDER BY blocked.pid LIMIT 50;"]}},{"id":"postgres.longest_running_queries","title":"Top 20 by query age","summary":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work.","description":"List backends in 'active' state, oldest first. Use to spot stuck/runaway work.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Long-runners","args":{}}],"search_terms":["db is slow","database slow","slow db","long running query","stuck query"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, usename, application_name, EXTRACT(EPOCH FROM (now()-query_start))::int AS age_sec, wait_event_type, wait_event, substring(query, 1, 300) AS query FROM pg_stat_activity WHERE state='active' AND pid <> pg_backend_pid() ORDER BY query_start ASC NULLS LAST LIMIT 20;"]}},{"id":"postgres.pg_hba_rules","title":"pg_hba_file_rules","summary":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","description":"List effective pg_hba rules as the server loaded them. Catches syntax errors that didn't make it in.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only — LDAP/RADIUS auth secrets are stripped from the options column."],"args":[],"examples":[{"title":"Hba rules","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT line_number, type, database, user_name, address, netmask, auth_method, array(SELECT o FROM unnest(options) AS o WHERE o NOT LIKE 'ldapbindpasswd=%' AND o NOT LIKE 'radiussecrets=%') AS options, error FROM pg_hba_file_rules ORDER BY line_number;"]}},{"id":"postgres.pg_stat_statements_reset","title":"pg_stat_statements_reset()","summary":"Clears accumulated pg_stat_statements counters. Use to start a clean measurement window.","description":"Clears accumulated pg_stat_statements counters. Use to start a clean measurement window.","kind":"exec","risk":"medium","side_effects":["All accumulated counters are reset to 0.","Future queries start from a clean baseline."],"args":[],"examples":[{"title":"Reset","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_stat_statements_reset();"]}},{"id":"postgres.pg_stat_statements_top","title":"Top statements by total time","summary":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded.","description":"Show the top 30 normalized queries by total_exec_time. Requires pg_stat_statements extension to be loaded.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","Read-only."],"args":[],"examples":[{"title":"Heavy hitters","args":{}}],"search_terms":["db is slow","database slow","slow db","expensive queries"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, ROUND(total_exec_time::numeric, 0) AS total_ms, ROUND(mean_exec_time::numeric, 1) AS mean_ms, rows, ROUND(100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0), 1) AS cache_hit_pct, substring(query, 1, 300) AS query FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 30;"]}},{"id":"postgres.progress_create_index","title":"pg_stat_progress_create_index","summary":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","description":"Show in-flight CREATE INDEX operations with phase + blocks scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live CREATE INDEXes","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, p.index_relid::regclass AS index, phase, blocks_total, blocks_done, tuples_total, tuples_done FROM pg_stat_progress_create_index p;"]}},{"id":"postgres.progress_vacuum","title":"pg_stat_progress_vacuum","summary":"Show in-flight VACUUMs with phase + heap_blks_scanned.","description":"Show in-flight VACUUMs with phase + heap_blks_scanned.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Live VACUUMs","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pid, datname, p.relid::regclass AS table, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, num_dead_tuples FROM pg_stat_progress_vacuum p;"]}},{"id":"postgres.reindex_concurrent","title":"REINDEX INDEX CONCURRENTLY <schema>.<index>","summary":"Rebuilds one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","description":"Rebuilds one index without blocking writes. Slower than plain REINDEX but no AccessExclusiveLock.","kind":"exec","risk":"high","side_effects":["New copy of the index is built alongside.","Old index dropped at end; brief lock at swap.","On failure, an _ccnew suffix index may be left behind."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"index","type":"string","required":true,"description":"Index name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}}],"examples":[{"title":"Rebuild bloated index","args":{"index":"orders_user_id_idx","schema":"public"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","REINDEX INDEX CONCURRENTLY {{ args.schema }}.{{ args.index }};"]}},{"id":"postgres.reload_conf","title":"Reload postgresql.conf","summary":"Calls `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","description":"Calls `pg_reload_conf()`. Re-reads the server config without restarting. Picks up changes to settings whose context is `sighup` (logging, autovacuum, work_mem, etc.); does NOT pick up settings marked `postmaster` (shared_buffers, listen_addresses) — those still require a restart. Safe in steady state but considered high-risk because a malformed config can break logging or reset connection limits.","kind":"exec","risk":"high","side_effects":["Server re-reads postgresql.conf and pg_hba.conf.","Active sessions keep their old settings until they reconnect for `user`-context settings; sighup-context settings apply immediately.","A malformed config logs a warning and keeps the previous values."],"args":[],"examples":[{"title":"Reload after editing postgresql.conf","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_reload_conf();"]}},{"id":"postgres.replication_lag","title":"Replication lag (primary view)","summary":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","description":"Show replication slot health from the primary's perspective. Surfaces sent/write/flush/replay LSNs plus the lag in bytes per replica. Run on the primary. Read-only. A lag >10 MB or a stalled flush_lsn is the usual signal that a downstream replica is in trouble.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_replication.","No locks held."],"args":[],"examples":[{"title":"How far behind are my replicas?","args":{}}],"search_terms":["replica out of sync","replication behind","standby lag"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT application_name, client_addr, state, sync_state, pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) AS sent_lag, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag FROM pg_stat_replication ORDER BY application_name;"]}},{"id":"postgres.replication_slots","title":"pg_replication_slots","summary":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","description":"List logical + physical replication slots with retained WAL. Inactive slots that retain WAL forever are a disk-full risk.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Slots","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT slot_name, slot_type, plugin, database, active, restart_lsn, confirmed_flush_lsn, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal FROM pg_replication_slots ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC NULLS LAST;"]}},{"id":"postgres.seq_scan_offenders","title":"Tables with high seq-scan ratio","summary":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","description":"List tables where seq_scan / (seq_scan + idx_scan) > 50% AND seq_tup_read > 100k. Candidates for missing indexes.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Seq scan offenders","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, seq_scan, idx_scan, seq_tup_read, idx_tup_fetch, ROUND(100.0 * seq_scan / NULLIF(seq_scan + idx_scan, 0), 2) AS seq_scan_pct, n_live_tup FROM pg_stat_user_tables WHERE seq_scan + idx_scan > 0 AND seq_tup_read > 100000 ORDER BY seq_tup_read DESC LIMIT 30;"]}},{"id":"postgres.settings_non_default","title":"pg_settings (non-default)","summary":"List settings the operator has changed from the compiled defaults.","description":"List settings the operator has changed from the compiled defaults.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Non-default settings","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT name, setting, unit, source, sourcefile, sourceline FROM pg_settings WHERE source NOT IN ('default', 'override') ORDER BY name;"]}},{"id":"postgres.slow_queries","title":"Top slow queries from pg_stat_statements","summary":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only.","description":"List the top N query fingerprints by mean execution time from pg_stat_statements. Requires the extension to be loaded (shared_preload_libraries = 'pg_stat_statements'); errors out cleanly if it isn't. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_statements.","No locks held."],"args":[{"name":"limit","type":"integer","required":false,"default":20,"description":"How many query fingerprints to return.","validation":{"min":1,"max":200}},{"name":"min_calls","type":"integer","required":false,"default":10,"description":"Skip query fingerprints with fewer than N total calls (filters one-off DDL noise).","validation":{"min":1,"max":100000}}],"examples":[{"title":"Top 20 slow queries (default)","args":{}},{"title":"Top 50 with at least 100 calls","args":{"limit":50,"min_calls":100}}],"search_terms":["db is slow","database slow","slow db","query performance"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT calls, round(mean_exec_time::numeric, 2) AS mean_ms, round(total_exec_time::numeric, 2) AS total_ms, left(query, 200) AS query FROM pg_stat_statements WHERE calls >= {{ args.min_calls }} ORDER BY mean_exec_time DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.ssl_connections","title":"pg_stat_ssl","summary":"List per-backend TLS state: version, cipher, client_serial.","description":"List per-backend TLS state: version, cipher, client_serial.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"TLS state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.pid, a.usename, a.application_name, s.ssl, s.version, s.cipher FROM pg_stat_ssl s JOIN pg_stat_activity a USING (pid) ORDER BY s.ssl DESC, s.pid LIMIT 100;"]}},{"id":"postgres.table_io","title":"pg_statio_user_tables","summary":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","description":"Show per-table heap + index buffer reads vs hits. Bad cache hit rate? Find the table.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Table IO","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname || '.' || relname AS table, heap_blks_read, heap_blks_hit, ROUND(100.0 * heap_blks_hit / NULLIF(heap_blks_hit + heap_blks_read, 0), 2) AS heap_hit_pct, idx_blks_read, idx_blks_hit, ROUND(100.0 * idx_blks_hit / NULLIF(idx_blks_hit + idx_blks_read, 0), 2) AS idx_hit_pct FROM pg_statio_user_tables ORDER BY heap_blks_read + idx_blks_read DESC LIMIT 50;"]}},{"id":"postgres.table_sizes","title":"Top tables by total size","summary":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","description":"List the top N tables by total size (heap + indexes + toast) for one schema. Use to find the table that's dominating disk before recommending vacuum, archive, or partitioning. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_class + pg_namespace.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"20 biggest tables in public","args":{}},{"title":"50 biggest tables in app schema","args":{"limit":50,"schema":"app"}}],"search_terms":["database out of space","db size","disk usage","largest tables"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT n.nspname AS schema, c.relname AS table, pg_size_pretty(pg_total_relation_size(c.oid)) AS total, pg_size_pretty(pg_relation_size(c.oid)) AS heap, pg_size_pretty(pg_indexes_size(c.oid)) AS indexes FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind = 'r' AND n.nspname = '{{ args.schema }}' ORDER BY pg_total_relation_size(c.oid) DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.terminate_backend","title":"pg_terminate_backend(pid)","summary":"Hard-disconnects one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","description":"Hard-disconnects one backend (SIGTERM). Use when pg_cancel_backend isn't enough (e.g., idle in transaction with a long held lock).","kind":"exec","risk":"high","side_effects":["Targeted backend's connection is severed.","Open transactions roll back.","Held locks are released."],"args":[{"name":"pid","type":"integer","required":true,"description":"Backend PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Kill one backend","args":{"pid":12345}}],"search_terms":["kill connection","kill session","force disconnect"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_terminate_backend({{ args.pid }});"]}},{"id":"postgres.unused_indexes","title":"Unused indexes (idx_scan = 0)","summary":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","description":"List indexes never used since last stats reset. Drop candidates — but verify they're not for an unrelated path (e.g., uniqueness constraint).","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Drop candidates","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT s.schemaname || '.' || s.relname AS table, s.indexrelname AS index, pg_size_pretty(pg_relation_size(s.indexrelid)) AS size, i.indisunique, i.indisprimary FROM pg_stat_user_indexes s JOIN pg_index i ON i.indexrelid = s.indexrelid WHERE s.idx_scan = 0 AND NOT i.indisunique AND NOT i.indisprimary ORDER BY pg_relation_size(s.indexrelid) DESC LIMIT 50;"]}},{"id":"postgres.uptime","title":"Postgres uptime and version","summary":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","description":"Show server uptime, version, and current connection count. Reads pg_stat_database + pg_postmaster_start_time(). Use as a first-touch sanity check before deeper diagnosis. Read-only.","kind":"exec","risk":"low","side_effects":["Issues two SELECTs against system catalogs.","No locks, no writes."],"args":[],"examples":[{"title":"Basic server uptime check","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT version(); SELECT pg_postmaster_start_time(); SELECT count(*) FROM pg_stat_activity;"]}},{"id":"postgres.vacuum_status","title":"Autovacuum + bloat snapshot","summary":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","description":"Show last-vacuum/last-autovacuum timestamps and dead-tuple counts for the top N tables in one schema, ordered by dead tuples. Use to decide whether to run VACUUM manually or tune autovacuum. Read-only.","kind":"exec","risk":"low","side_effects":["One SELECT against pg_stat_user_tables.","No locks held."],"args":[{"name":"schema","type":"string","required":false,"default":"public","description":"Schema to inspect.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"limit","type":"integer","required":false,"default":20,"description":"How many tables to return.","validation":{"min":1,"max":200}}],"examples":[{"title":"Find tables with the most dead rows","args":{}}],"search_terms":["vacuum not running","table bloat"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT schemaname, relname, n_live_tup, n_dead_tup, round(100 * n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE schemaname = '{{ args.schema }}' ORDER BY n_dead_tup DESC LIMIT {{ args.limit }};"]}},{"id":"postgres.vacuum_table","title":"VACUUM <schema>.<table>","summary":"Reclaims dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","description":"Reclaims dead-tuple space in one table. Non-blocking (ShareUpdateExclusiveLock). Use VACUUM ANALYZE if planner stats are also stale.","kind":"exec","risk":"high","side_effects":["IO-heavy proportional to table size.","DML continues during the vacuum.","Does NOT shrink the table file — for that, use VACUUM FULL (not exposed here; rebuilds the table with AccessExclusiveLock)."],"args":[{"name":"schema","type":"string","required":true,"description":"Schema name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"table","type":"string","required":true,"description":"Table name.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,62}$"}},{"name":"analyze","type":"boolean","required":false,"default":true,"description":"Also run ANALYZE."}],"examples":[{"title":"VACUUM ANALYZE one table","args":{"schema":"public","table":"orders"}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","VACUUM (VERBOSE, ANALYZE {{ args.analyze }}) {{ args.schema }}.{{ args.table }};"]}},{"id":"postgres.wal_archive_status","title":"pg_stat_archiver","summary":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","description":"Show WAL archiver stats: archived/failed counts, last archived WAL, last failure.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Archiver","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT * FROM pg_stat_archiver;"]}},{"id":"postgres.wal_status","title":"Current WAL LSN + recovery state","summary":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","description":"Show a snapshot of current WAL LSN, last receive/replay LSNs, recovery state.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"WAL state","args":{}}],"search_terms":[],"command":{"binary":"psql","argv":["-XAt","-c","SELECT pg_is_in_recovery() AS in_recovery, CASE WHEN pg_is_in_recovery() THEN NULL ELSE pg_current_wal_lsn() END AS current_lsn, pg_last_wal_receive_lsn() AS last_receive_lsn, pg_last_wal_replay_lsn() AS last_replay_lsn, pg_last_xact_replay_timestamp() AS last_replay_time;"]}},{"id":"postgres.xid_wraparound_proximity","title":"How close are we to XID wraparound?","summary":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","description":"Show per-database age(datfrozenxid). 2^31 (~2.1B) is the wraparound limit. >1B = pay attention; >1.8B = emergency.","kind":"exec","risk":"low","side_effects":["One SELECT.","Read-only."],"args":[],"examples":[{"title":"Wraparound risk","args":{}}],"search_terms":["transaction id wraparound","vacuum freeze age"],"command":{"binary":"psql","argv":["-XAt","-c","SELECT datname, age(datfrozenxid) AS xid_age, ROUND(100.0 * age(datfrozenxid) / 2147483648.0, 2) AS pct_to_wraparound FROM pg_database ORDER BY age(datfrozenxid) DESC;"]}}]}]},{"id":"process-forensics","name":"Process forensics","version":"0.1.8","description":"Deep per-process diagnostics for \"why is this process stuck / slow / leaking?\" — strace (HIGH RISK; slows the target), pid memory maps, per-thread state, /proc walking, gdb backtrace, full lsof, syscall summary. Read-only — but strace and gdb attach via ptrace and WILL slow the target.","vendor":"emisar","homepage":"https://emisar.dev/packs/process-forensics","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/process-forensics","content_hash":"sha256:5953997cdca2410aed1a1b9bba396cf0ea85731c4a1e8c4ddd034fca14d83b6c","tarball_url":"https://registry.emisar.dev/v1/packs/process-forensics/0.1.8/5953997cdca2410aed1a1b9bba396cf0ea85731c4a1e8c4ddd034fca14d83b6c/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Inspects processes on the local runner host — no credentials needed.","host_access":[{"actions":["forensics.pid_maps","forensics.pid_smaps_summary","forensics.pid_threads_state","forensics.pid_open_files","forensics.pid_status","forensics.pid_io","forensics.pid_syscall","forensics.strace_pid_short","forensics.gdb_backtrace","forensics.strace_summary"],"requirement":"Inspect and attach to processes owned by other users.","recipes":[{"name":"Grant CAP_SYS_PTRACE to the Emisar service","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'AmbientCapabilities=CAP_SYS_PTRACE' | sudo tee /etc/systemd/system/emisar.service.d/10-process-forensics-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["systemctl show emisar --property=AmbientCapabilities --value | grep -Fwi cap_sys_ptrace"],"impact":"Every Emisar action on this runner inherits CAP_SYS_PTRACE and can inspect or attach to processes outside the runner user, including their memory and secrets."}]}],"verify":"forensics.pid_status"},"actions":[{"id":"forensics.gdb_backtrace","title":"gdb -ex \"thread apply all bt\"","summary":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","description":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","kind":"exec","risk":"high","side_effects":["Target process is paused for the duration of the gdb session (typically 0.5-3 seconds).","Requires CAP_SYS_PTRACE or matching uid.","On detach, target resumes."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"All-thread backtrace","args":{"pid":1234}}],"search_terms":["stack trace","process hung","where is it stuck"],"command":{"binary":"/bin/sh","argv":["-c","gdb -p {{ args.pid }} -batch -ex 'set pagination off' -ex 'thread apply all bt' -ex 'detach' -ex 'quit' 2>&1 | head -5000"]}},{"id":"forensics.pid_io","title":"/proc/PID/io","summary":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","description":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"IO of PID 1","args":{"pid":1}}],"search_terms":["io hog","disk io per process"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"forensics.pid_maps","title":"/proc/PID/maps","summary":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","description":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Map of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/maps"]}},{"id":"forensics.pid_open_files","title":"lsof -p <pid>","summary":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","description":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","kind":"exec","risk":"low","side_effects":["lsof walks /proc + kernel tables.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Open files for PID 1","args":{"pid":1}}],"search_terms":["fd leak","file descriptor leak","too many open files"],"command":{"binary":"lsof","argv":["-p","{{ args.pid }}"]}},{"id":"forensics.pid_smaps_summary","title":"/proc/PID/smaps_rollup","summary":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","description":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Memory rollup","args":{"pid":1}}],"search_terms":["memory leak","process memory usage"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/smaps_rollup"]}},{"id":"forensics.pid_status","title":"/proc/PID/status","summary":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","description":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"forensics.pid_syscall","title":"/proc/PID/syscall","summary":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","description":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Current syscall","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/syscall"]}},{"id":"forensics.pid_threads_state","title":"Per-thread state for one PID","summary":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","description":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","kind":"exec","risk":"low","side_effects":["Reads /proc/PID/task/.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Per-thread state of PID 1","args":{"pid":1}}],"search_terms":["d state","uninterruptible sleep","zombie threads"],"command":{"binary":"/bin/sh","argv":["-c","for f in /proc/{{ args.pid }}/task/*/status; do tid=$(basename $(dirname $f)); awk -v tid=$tid '/^State:/ {print tid, $2, $3}' $f; done | sort -k2"]}},{"id":"forensics.strace_pid_short","title":"strace -p <pid> (5 seconds)","summary":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","description":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","kind":"exec","risk":"high","side_effects":["Target process runs ~5-20x slower during the strace window.","On detach, target resumes normal speed.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"5s strace of PID","args":{"pid":1234}}],"search_terms":["what is this process doing","process hung","trace system calls"],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 strace -p {{ args.pid }} -y -tt 2>&1); status=$?; printf '%s\\n' \"$out\" | head -2000; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac"]}},{"id":"forensics.strace_summary","title":"strace -c -p <pid> (5 seconds)","summary":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","description":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","kind":"exec","risk":"high","side_effects":["Target process runs ~3-10x slower during the window.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Syscall frequency for PID","args":{"pid":1234}}],"search_terms":["syscall counts"],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 strace -c -p {{ args.pid }} 2>&1); status=$?; printf '%s\\n' \"$out\"; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac"]}}],"previous_versions":[{"version":"0.1.7","content_hash":"sha256:ebc881a50958089ae07565699574cca65d4cfaddd665f7c80256cccd81a8c4de","tarball_url":"https://registry.emisar.dev/v1/packs/process-forensics/0.1.7/ebc881a50958089ae07565699574cca65d4cfaddd665f7c80256cccd81a8c4de/pack.tar.gz","actions":[{"id":"forensics.gdb_backtrace","title":"gdb -ex \"thread apply all bt\"","summary":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","description":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","kind":"exec","risk":"high","side_effects":["Target process is paused for the duration of the gdb session (typically 0.5-3 seconds).","Requires CAP_SYS_PTRACE or matching uid.","On detach, target resumes."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"All-thread backtrace","args":{"pid":1234}}],"search_terms":["stack trace","process hung","where is it stuck"],"command":{"binary":"/bin/sh","argv":["-c","gdb -p {{ args.pid }} -batch -ex 'set pagination off' -ex 'thread apply all bt' -ex 'detach' -ex 'quit' 2>&1 | head -5000"]}},{"id":"forensics.pid_io","title":"/proc/PID/io","summary":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","description":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"IO of PID 1","args":{"pid":1}}],"search_terms":["io hog","disk io per process"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"forensics.pid_maps","title":"/proc/PID/maps","summary":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","description":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Map of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/maps"]}},{"id":"forensics.pid_open_files","title":"lsof -p <pid>","summary":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","description":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","kind":"exec","risk":"low","side_effects":["lsof walks /proc + kernel tables.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Open files for PID 1","args":{"pid":1}}],"search_terms":["fd leak","file descriptor leak","too many open files"],"command":{"binary":"lsof","argv":["-p","{{ args.pid }}"]}},{"id":"forensics.pid_smaps_summary","title":"/proc/PID/smaps_rollup","summary":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","description":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Memory rollup","args":{"pid":1}}],"search_terms":["memory leak","process memory usage"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/smaps_rollup"]}},{"id":"forensics.pid_status","title":"/proc/PID/status","summary":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","description":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"forensics.pid_syscall","title":"/proc/PID/syscall","summary":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","description":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Current syscall","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/syscall"]}},{"id":"forensics.pid_threads_state","title":"Per-thread state for one PID","summary":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","description":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","kind":"exec","risk":"low","side_effects":["Reads /proc/PID/task/.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Per-thread state of PID 1","args":{"pid":1}}],"search_terms":["d state","uninterruptible sleep","zombie threads"],"command":{"binary":"/bin/sh","argv":["-c","for f in /proc/{{ args.pid }}/task/*/status; do tid=$(basename $(dirname $f)); awk -v tid=$tid '/^State:/ {print tid, $2, $3}' $f; done | sort -k2"]}},{"id":"forensics.strace_pid_short","title":"strace -p <pid> (5 seconds)","summary":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","description":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","kind":"exec","risk":"high","side_effects":["Target process runs ~5-20x slower during the strace window.","On detach, target resumes normal speed.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"5s strace of PID","args":{"pid":1234}}],"search_terms":["what is this process doing","process hung","trace system calls"],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 strace -p {{ args.pid }} -y -tt 2>&1); status=$?; printf '%s\\n' \"$out\" | head -2000; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac"]}},{"id":"forensics.strace_summary","title":"strace -c -p <pid> (5 seconds)","summary":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","description":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","kind":"exec","risk":"high","side_effects":["Target process runs ~3-10x slower during the window.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Syscall frequency for PID","args":{"pid":1234}}],"search_terms":["syscall counts"],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 strace -c -p {{ args.pid }} 2>&1); status=$?; printf '%s\\n' \"$out\"; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac"]}}]},{"version":"0.1.6","content_hash":"sha256:d0aa63cea711b803c1c82ce9cc74a9108f3720dd265239126d8487241f8d87a7","tarball_url":"https://registry.emisar.dev/v1/packs/process-forensics/0.1.6/d0aa63cea711b803c1c82ce9cc74a9108f3720dd265239126d8487241f8d87a7/pack.tar.gz","actions":[{"id":"forensics.gdb_backtrace","title":"gdb -ex \"thread apply all bt\"","summary":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","description":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","kind":"exec","risk":"high","side_effects":["Target process is paused for the duration of the gdb session (typically 0.5-3 seconds).","Requires CAP_SYS_PTRACE or matching uid.","On detach, target resumes."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"All-thread backtrace","args":{"pid":1234}}],"search_terms":["stack trace","process hung","where is it stuck"],"command":{"binary":"/bin/sh","argv":["-c","gdb -p {{ args.pid }} -batch -ex 'set pagination off' -ex 'thread apply all bt' -ex 'detach' -ex 'quit' 2>&1 | head -5000"]}},{"id":"forensics.pid_io","title":"/proc/PID/io","summary":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","description":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"IO of PID 1","args":{"pid":1}}],"search_terms":["io hog","disk io per process"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"forensics.pid_maps","title":"/proc/PID/maps","summary":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","description":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Map of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/maps"]}},{"id":"forensics.pid_open_files","title":"lsof -p <pid>","summary":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","description":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","kind":"exec","risk":"low","side_effects":["lsof walks /proc + kernel tables.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Open files for PID 1","args":{"pid":1}}],"search_terms":["fd leak","file descriptor leak","too many open files"],"command":{"binary":"lsof","argv":["-p","{{ args.pid }}"]}},{"id":"forensics.pid_smaps_summary","title":"/proc/PID/smaps_rollup","summary":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","description":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Memory rollup","args":{"pid":1}}],"search_terms":["memory leak","process memory usage"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/smaps_rollup"]}},{"id":"forensics.pid_status","title":"/proc/PID/status","summary":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","description":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"forensics.pid_syscall","title":"/proc/PID/syscall","summary":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","description":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Current syscall","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/syscall"]}},{"id":"forensics.pid_threads_state","title":"Per-thread state for one PID","summary":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","description":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","kind":"exec","risk":"low","side_effects":["Reads /proc/PID/task/.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Per-thread state of PID 1","args":{"pid":1}}],"search_terms":["d state","uninterruptible sleep","zombie threads"],"command":{"binary":"/bin/sh","argv":["-c","for f in /proc/{{ args.pid }}/task/*/status; do tid=$(basename $(dirname $f)); awk -v tid=$tid '/^State:/ {print tid, $2, $3}' $f; done | sort -k2"]}},{"id":"forensics.strace_pid_short","title":"strace -p <pid> (5 seconds)","summary":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","description":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","kind":"exec","risk":"high","side_effects":["Target process runs ~5-20x slower during the strace window.","On detach, target resumes normal speed.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"5s strace of PID","args":{"pid":1234}}],"search_terms":["what is this process doing","process hung","trace system calls"],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 strace -p {{ args.pid }} -y -tt 2>&1); status=$?; printf '%s\\n' \"$out\" | head -2000; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac"]}},{"id":"forensics.strace_summary","title":"strace -c -p <pid> (5 seconds)","summary":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","description":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","kind":"exec","risk":"high","side_effects":["Target process runs ~3-10x slower during the window.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Syscall frequency for PID","args":{"pid":1234}}],"search_terms":["syscall counts"],"command":{"binary":"/bin/sh","argv":["-c","out=$(timeout 5 strace -c -p {{ args.pid }} 2>&1); status=$?; printf '%s\\n' \"$out\"; case \"$status\" in 0|124) exit 0 ;; *) exit \"$status\" ;; esac"]}}]},{"version":"0.1.5","content_hash":"sha256:0dbc117300e6b3acd167e2f6fe580f4df414f773479e8c8b90b9ccdf135b60e8","tarball_url":"https://registry.emisar.dev/v1/packs/process-forensics/0.1.5/0dbc117300e6b3acd167e2f6fe580f4df414f773479e8c8b90b9ccdf135b60e8/pack.tar.gz","actions":[{"id":"forensics.gdb_backtrace","title":"gdb -ex \"thread apply all bt\"","summary":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","description":"Attach gdb to one PID and dump native stack for every thread, then detach. The target is briefly stopped during the dump.","kind":"exec","risk":"high","side_effects":["Target process is paused for the duration of the gdb session (typically 0.5-3 seconds).","Requires CAP_SYS_PTRACE or matching uid.","On detach, target resumes."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"All-thread backtrace","args":{"pid":1234}}],"search_terms":["stack trace","process hung","where is it stuck"],"command":{"binary":"/bin/sh","argv":["-c","gdb -p {{ args.pid }} -batch -ex 'set pagination off' -ex 'thread apply all bt' -ex 'detach' -ex 'quit' 2>&1 | head -5000"]}},{"id":"forensics.pid_io","title":"/proc/PID/io","summary":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","description":"Show cumulative read/write byte counts for one PID. Use to identify IO hogs.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"IO of PID 1","args":{"pid":1}}],"search_terms":["io hog","disk io per process"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/io"]}},{"id":"forensics.pid_maps","title":"/proc/PID/maps","summary":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","description":"Show memory map for one PID. Use to see loaded libraries + heap/stack ranges.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Map of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/maps"]}},{"id":"forensics.pid_open_files","title":"lsof -p <pid>","summary":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","description":"List all open files (regular, sockets, pipes) for one PID. Richer than /proc/PID/fd alone.","kind":"exec","risk":"low","side_effects":["lsof walks /proc + kernel tables.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Open files for PID 1","args":{"pid":1}}],"search_terms":["fd leak","file descriptor leak","too many open files"],"command":{"binary":"lsof","argv":["-p","{{ args.pid }}"]}},{"id":"forensics.pid_smaps_summary","title":"/proc/PID/smaps_rollup","summary":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","description":"Show aggregated memory stats — Rss, Pss, Shared, Private. Better than RSS for diagnosing memory pressure.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Memory rollup","args":{"pid":1}}],"search_terms":["memory leak","process memory usage"],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/smaps_rollup"]}},{"id":"forensics.pid_status","title":"/proc/PID/status","summary":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","description":"Show full /proc/PID/status — uid/gid, capability set, signal state, oom score.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Status of PID 1","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/status"]}},{"id":"forensics.pid_syscall","title":"/proc/PID/syscall","summary":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","description":"Show current syscall (or \"running\" if user-space). Snapshot of where the kernel is for one thread.","kind":"exec","risk":"low","side_effects":["One /proc read.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Current syscall","args":{"pid":1}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/{{ args.pid }}/syscall"]}},{"id":"forensics.pid_threads_state","title":"Per-thread state for one PID","summary":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","description":"Tabulate each thread's state (R/S/D/Z) from /proc/PID/task/*/status.","kind":"exec","risk":"low","side_effects":["Reads /proc/PID/task/.","Read-only."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Per-thread state of PID 1","args":{"pid":1}}],"search_terms":["d state","uninterruptible sleep","zombie threads"],"command":{"binary":"/bin/sh","argv":["-c","for f in /proc/{{ args.pid }}/task/*/status; do tid=$(basename $(dirname $f)); awk -v tid=$tid '/^State:/ {print tid, $2, $3}' $f; done | sort -k2"]}},{"id":"forensics.strace_pid_short","title":"strace -p <pid> (5 seconds)","summary":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","description":"Attach strace to one PID for 5 seconds. Slows the target process significantly while attached. Detaches automatically.","kind":"exec","risk":"high","side_effects":["Target process runs ~5-20x slower during the strace window.","On detach, target resumes normal speed.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"5s strace of PID","args":{"pid":1234}}],"search_terms":["what is this process doing","process hung","trace system calls"],"command":{"binary":"/bin/sh","argv":["-c","timeout 5 strace -p {{ args.pid }} -y -tt 2>&1 | head -2000 || true"]}},{"id":"forensics.strace_summary","title":"strace -c -p <pid> (5 seconds)","summary":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","description":"Attach strace in counting mode for 5 seconds — outputs a syscall-frequency table. Slows target less than -y mode but still significant.","kind":"exec","risk":"high","side_effects":["Target process runs ~3-10x slower during the window.","Requires CAP_SYS_PTRACE or matching uid."],"args":[{"name":"pid","type":"integer","required":true,"description":"PID.","validation":{"min":1,"max":4194304}}],"examples":[{"title":"Syscall frequency for PID","args":{"pid":1234}}],"search_terms":["syscall counts"],"command":{"binary":"/bin/sh","argv":["-c","timeout 5 strace -c -p {{ args.pid }} 2>&1 || true"]}}]}]},{"id":"prometheus","name":"Prometheus operations","version":"0.1.18","description":"Server status, target health, alertmanager linkage, instant + range queries, rule listing, TSDB stats, plus admin-API actions for remediation: reload config, take snapshot, clean tombstones, delete series. Admin endpoints require --web.enable-admin-api + --web.enable-lifecycle.","vendor":"emisar","homepage":"https://emisar.dev/packs/prometheus","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/prometheus","content_hash":"sha256:0fad07f29b6644c72cabb02b8b27ba2d4b83baec4de40b9b2b1feeb60eb7e8ff","tarball_url":"https://registry.emisar.dev/v1/packs/prometheus/0.1.18/0fad07f29b6644c72cabb02b8b27ba2d4b83baec4de40b9b2b1feeb60eb7e8ff/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["prometheus"],"ports":[9090]},"setup":{"summary":"Every action calls the Prometheus HTTP API at `$PROM_URL` via curl on the runner host. Set `PROM_URL` to the server base URL; the actions send no auth, so a reachable endpoint is all that is needed.","env":[{"name":"PROM_URL","description":"Prometheus base URL (scheme + host + port, no trailing path). Defaults to a local Prometheus.","default":"http://127.0.0.1:9090","example":"http://prometheus.internal:9090"}],"notes":["Any of `PROM_URL` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","No credentials are sent. If your Prometheus sits behind an auth proxy, expose it to the runner on a network path that does not require a header, or point `PROM_URL` at a trusted side door.","Admin actions (reload_config, snapshot, clean_tombstones, delete_series) only work if Prometheus was started with --web.enable-admin-api and --web.enable-lifecycle.","Range queries are limited to 7 days and 10,081 outer evaluation timestamps per returned series, with a 30-second provider-side timeout. This preserves a full week at one-minute resolution; query cardinality, range-vector lookbacks, and subqueries can still add cost."],"verify":"prom.build_info"},"actions":[{"id":"prom.alertmanagers","title":"GET /api/v1/alertmanagers","summary":"List configured Alertmanager endpoints + their reachability.","description":"List configured Alertmanager endpoints + their reachability.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Alertmanagers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/alertmanagers\""]}},{"id":"prom.alerts","title":"GET /api/v1/alerts","summary":"List currently active alerts (pending or firing).","description":"List currently active alerts (pending or firing).","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Active alerts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/alerts\""]}},{"id":"prom.build_info","title":"GET /api/v1/status/buildinfo","summary":"Show Prometheus version + build details.","description":"Show Prometheus version + build details.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/buildinfo\""]}},{"id":"prom.clean_tombstones","title":"POST /api/v1/admin/tsdb/clean_tombstones","summary":"Reclaim disk space after a delete_series call. Tombstones are removed and the data they marked is permanently deleted.","description":"Reclaim disk space after a delete_series call. Tombstones are removed and the data they marked is permanently deleted.","kind":"exec","risk":"high","side_effects":["Tombstoned series permanently deleted from disk.","Disk usage drops.","Brief I/O spike."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reclaim after a delete","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.target }}/api/v1/admin/tsdb/clean_tombstones"]}},{"id":"prom.delete_series","title":"POST /api/v1/admin/tsdb/delete_series","summary":"Mark series matching the matcher as deleted (tombstoned). Series no longer return from queries. Run clean_tombstones afterwards to actually reclaim disk. Use to remove cardinality-explosion mistakes or accidentally-recorded secrets. Match pattern is restricted to safe label-selector characters.","description":"Mark series matching the matcher as deleted (tombstoned). Series no longer return from queries. Run clean_tombstones afterwards to actually reclaim disk. Use to remove cardinality-explosion mistakes or accidentally-recorded secrets. Match pattern is restricted to safe label-selector characters.","kind":"exec","risk":"high","side_effects":["Matching series tombstoned (logical delete).","Queries no longer return them.","Disk only reclaimed after clean_tombstones."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"matcher","type":"string","required":true,"description":"Label matcher (URL-encoded if it contains special chars).","validation":{"pattern":"^[a-zA-Z0-9_={}\",.:!~=\\-/%* ]{1,512}$"}}],"examples":[{"title":"Delete a cardinality mistake","args":{"matcher":"{__name__=\"bad_metric\"}"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -sSf --globoff --proto =http,https -X POST --data-urlencode 'match[]='\"$1\"'' ''\"$2\"'/api/v1/admin/tsdb/delete_series'","emisar","{{ args.matcher }}","{{ args.target }}"]}},{"id":"prom.flags","title":"GET /api/v1/status/flags","summary":"Show server command-line flags.","description":"Show server command-line flags.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"CLI flags","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/flags\""]}},{"id":"prom.query_instant","title":"GET /api/v1/query","summary":"Run an instant PromQL query. Use to answer 'what's X right now?'.","description":"Run an instant PromQL query. Use to answer 'what's X right now?'.","kind":"exec","risk":"low","side_effects":["One PromQL query.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL expression.","validation":{"pattern":"^.{1,1000}$"}}],"examples":[{"title":"Up status","args":{"query":"up"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https -G --data-urlencode \"query=$Q\" \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/query\""]}},{"id":"prom.query_range","title":"GET /api/v1/query_range","summary":"Run a range PromQL query over a trailing window ending now. The window is limited to 7 days and the window-to-step ratio to 10,081 evaluation timestamps per returned series. Use for bounded trends and incident graphs.","description":"Run a range PromQL query over a trailing window ending now. The window is limited to 7 days and the window-to-step ratio to 10,081 evaluation timestamps per returned series. Use for bounded trends and incident graphs.","kind":"script","risk":"low","side_effects":["One PromQL range query — can be expensive on large series.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL expression.","validation":{"pattern":"^.{1,1000}$"}},{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing window ending now, up to 7d, e.g. 1h, 6h, 24h, 7d.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhd]$"}},{"name":"step","type":"string","required":false,"default":"60s","description":"Resolution between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[sm]$"}}],"examples":[{"title":"1h CPU usage","args":{"query":"rate(node_cpu_seconds_total[5m])","step":"60s","window":"1h"}},{"title":"One week at one-minute resolution","args":{"query":"sum(rate(http_requests_total[5m]))","step":"1m","window":"7d"}}],"search_terms":[]},{"id":"prom.reload_config","title":"POST /-/reload","summary":"Trigger Prometheus to reload its config + rule files in place. Requires --web.enable-lifecycle. If the new config is invalid, reload fails and Prometheus keeps the old one.","description":"Trigger Prometheus to reload its config + rule files in place. Requires --web.enable-lifecycle. If the new config is invalid, reload fails and Prometheus keeps the old one.","kind":"exec","risk":"high","side_effects":["Prometheus re-reads prometheus.yml + rule files.","Brief scrape pause during reload.","Failure leaves the old config in place."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.target }}/-/reload"]}},{"id":"prom.rules","title":"GET /api/v1/rules","summary":"List all loaded recording + alerting rules with last evaluation result.","description":"List all loaded recording + alerting rules with last evaluation result.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Rules","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/rules\""]}},{"id":"prom.runtime_info","title":"GET /api/v1/status/runtimeinfo","summary":"Show uptime, last config reload, chunk count, WAL corrected/unprocessed.","description":"Show uptime, last config reload, chunk count, WAL corrected/unprocessed.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Runtime info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/runtimeinfo\""]}},{"id":"prom.snapshot","title":"POST /api/v1/admin/tsdb/snapshot","summary":"Trigger an on-disk snapshot of the TSDB into data/snapshots/. Requires --web.enable-admin-api. Used before risky upgrades or for offline diff. Uses hardlinks initially — no extra disk until blocks rotate.","description":"Trigger an on-disk snapshot of the TSDB into data/snapshots/. Requires --web.enable-admin-api. Used before risky upgrades or for offline diff. Uses hardlinks initially — no extra disk until blocks rotate.","kind":"exec","risk":"medium","side_effects":["New snapshot directory under data/snapshots/.","Brief I/O spike.","Disk usage grows as blocks change over time."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"skip_head","type":"boolean","required":false,"default":false,"description":"Skip the in-memory head block (faster, less complete)."}],"examples":[{"title":"Full snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -sSf --globoff --proto =http,https -X POST ''\"$1\"'/api/v1/admin/tsdb/snapshot?skip_head={{ args.skip_head }}'","emisar","{{ args.target }}"]}},{"id":"prom.targets","title":"GET /api/v1/targets","summary":"List all scrape targets with state (up/down) and last error.","description":"List all scrape targets with state (up/down) and last error.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All targets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/targets\""]}},{"id":"prom.tsdb_stats","title":"GET /api/v1/status/tsdb","summary":"Show the top-10 cardinal label/value pairs in the TSDB. Use to spot cardinality explosion.","description":"Show the top-10 cardinal label/value pairs in the TSDB. Use to spot cardinality explosion.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"TSDB cardinality","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/tsdb\""]}}],"previous_versions":[{"version":"0.1.16","content_hash":"sha256:0359128d29e688370aa1802210a833586203003482a3d9aa9e60e7a532516165","tarball_url":"https://registry.emisar.dev/v1/packs/prometheus/0.1.16/0359128d29e688370aa1802210a833586203003482a3d9aa9e60e7a532516165/pack.tar.gz","actions":[{"id":"prom.alertmanagers","title":"GET /api/v1/alertmanagers","summary":"List configured Alertmanager endpoints + their reachability.","description":"List configured Alertmanager endpoints + their reachability.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Alertmanagers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/alertmanagers\""]}},{"id":"prom.alerts","title":"GET /api/v1/alerts","summary":"List currently active alerts (pending or firing).","description":"List currently active alerts (pending or firing).","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Active alerts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/alerts\""]}},{"id":"prom.build_info","title":"GET /api/v1/status/buildinfo","summary":"Show Prometheus version + build details.","description":"Show Prometheus version + build details.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Build info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/buildinfo\""]}},{"id":"prom.clean_tombstones","title":"POST /api/v1/admin/tsdb/clean_tombstones","summary":"Reclaim disk space after a delete_series call. Tombstones are removed and the data they marked is permanently deleted.","description":"Reclaim disk space after a delete_series call. Tombstones are removed and the data they marked is permanently deleted.","kind":"exec","risk":"high","side_effects":["Tombstoned series permanently deleted from disk.","Disk usage drops.","Brief I/O spike."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reclaim after a delete","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.target }}/api/v1/admin/tsdb/clean_tombstones"]}},{"id":"prom.delete_series","title":"POST /api/v1/admin/tsdb/delete_series","summary":"Mark series matching the matcher as deleted (tombstoned). Series no longer return from queries. Run clean_tombstones afterwards to actually reclaim disk. Use to remove cardinality-explosion mistakes or accidentally-recorded secrets. Match pattern is restricted to safe label-selector characters.","description":"Mark series matching the matcher as deleted (tombstoned). Series no longer return from queries. Run clean_tombstones afterwards to actually reclaim disk. Use to remove cardinality-explosion mistakes or accidentally-recorded secrets. Match pattern is restricted to safe label-selector characters.","kind":"exec","risk":"high","side_effects":["Matching series tombstoned (logical delete).","Queries no longer return them.","Disk only reclaimed after clean_tombstones."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"matcher","type":"string","required":true,"description":"Label matcher (URL-encoded if it contains special chars).","validation":{"pattern":"^[a-zA-Z0-9_={}\",.:!~=\\-/%* ]{1,512}$"}}],"examples":[{"title":"Delete a cardinality mistake","args":{"matcher":"{__name__=\"bad_metric\"}"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -sSfX --globoff --proto =http,https POST --data-urlencode 'match[]='\"$1\"'' ''\"$2\"'/api/v1/admin/tsdb/delete_series'","emisar","{{ args.matcher }}","{{ args.target }}"]}},{"id":"prom.flags","title":"GET /api/v1/status/flags","summary":"Show server command-line flags.","description":"Show server command-line flags.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"CLI flags","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/flags\""]}},{"id":"prom.query_instant","title":"GET /api/v1/query","summary":"Run an instant PromQL query. Use to answer 'what's X right now?'.","description":"Run an instant PromQL query. Use to answer 'what's X right now?'.","kind":"exec","risk":"low","side_effects":["One PromQL query.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL expression.","validation":{"pattern":"^.{1,1000}$"}}],"examples":[{"title":"Up status","args":{"query":"up"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -G --data-urlencode \"query=$Q\" \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/query\""]}},{"id":"prom.query_range","title":"GET /api/v1/query_range","summary":"Run a range PromQL query over a trailing window ending now. The window is limited to 7 days and the window-to-step ratio to 10,081 evaluation timestamps per returned series. Use for bounded trends and incident graphs.","description":"Run a range PromQL query over a trailing window ending now. The window is limited to 7 days and the window-to-step ratio to 10,081 evaluation timestamps per returned series. Use for bounded trends and incident graphs.","kind":"script","risk":"low","side_effects":["One PromQL range query — can be expensive on large series.","Read-only."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL expression.","validation":{"pattern":"^.{1,1000}$"}},{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing window ending now, up to 7d, e.g. 1h, 6h, 24h, 7d.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhd]$"}},{"name":"step","type":"string","required":false,"default":"60s","description":"Resolution between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[sm]$"}}],"examples":[{"title":"1h CPU usage","args":{"query":"rate(node_cpu_seconds_total[5m])","step":"60s","window":"1h"}},{"title":"One week at one-minute resolution","args":{"query":"sum(rate(http_requests_total[5m]))","step":"1m","window":"7d"}}],"search_terms":[]},{"id":"prom.reload_config","title":"POST /-/reload","summary":"Trigger Prometheus to reload its config + rule files in place. Requires --web.enable-lifecycle. If the new config is invalid, reload fails and Prometheus keeps the old one.","description":"Trigger Prometheus to reload its config + rule files in place. Requires --web.enable-lifecycle. If the new config is invalid, reload fails and Prometheus keeps the old one.","kind":"exec","risk":"high","side_effects":["Prometheus re-reads prometheus.yml + rule files.","Brief scrape pause during reload.","Failure leaves the old config in place."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}}],"examples":[{"title":"Reload config","args":{}}],"search_terms":[],"command":{"binary":"curl","argv":["-sSfX","POST","--globoff","--proto","=http,https","{{ args.target }}/-/reload"]}},{"id":"prom.rules","title":"GET /api/v1/rules","summary":"List all loaded recording + alerting rules with last evaluation result.","description":"List all loaded recording + alerting rules with last evaluation result.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Rules","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/rules\""]}},{"id":"prom.runtime_info","title":"GET /api/v1/status/runtimeinfo","summary":"Show uptime, last config reload, chunk count, WAL corrected/unprocessed.","description":"Show uptime, last config reload, chunk count, WAL corrected/unprocessed.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"Runtime info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/runtimeinfo\""]}},{"id":"prom.snapshot","title":"POST /api/v1/admin/tsdb/snapshot","summary":"Trigger an on-disk snapshot of the TSDB into data/snapshots/. Requires --web.enable-admin-api. Used before risky upgrades or for offline diff. Uses hardlinks initially — no extra disk until blocks rotate.","description":"Trigger an on-disk snapshot of the TSDB into data/snapshots/. Requires --web.enable-admin-api. Used before risky upgrades or for offline diff. Uses hardlinks initially — no extra disk until blocks rotate.","kind":"exec","risk":"medium","side_effects":["New snapshot directory under data/snapshots/.","Brief I/O spike.","Disk usage grows as blocks change over time."],"args":[{"name":"target","type":"string","required":false,"default":"http://localhost:9090","description":"Prometheus base URL.","validation":{"pattern":"^https?://[a-zA-Z0-9._:\\-]{1,253}(:[0-9]{1,5})?$"}},{"name":"skip_head","type":"boolean","required":false,"default":false,"description":"Skip the in-memory head block (faster, less complete)."}],"examples":[{"title":"Full snapshot","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -sSfX --globoff --proto =http,https POST ''\"$1\"'/api/v1/admin/tsdb/snapshot?skip_head={{ args.skip_head }}'","emisar","{{ args.target }}"]}},{"id":"prom.targets","title":"GET /api/v1/targets","summary":"List all scrape targets with state (up/down) and last error.","description":"List all scrape targets with state (up/down) and last error.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"All targets","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/targets\""]}},{"id":"prom.tsdb_stats","title":"GET /api/v1/status/tsdb","summary":"Show the top-10 cardinal label/value pairs in the TSDB. Use to spot cardinality explosion.","description":"Show the top-10 cardinal label/value pairs in the TSDB. Use to spot cardinality explosion.","kind":"exec","risk":"low","side_effects":["One GET request.","Read-only."],"args":[],"examples":[{"title":"TSDB cardinality","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${PROM_URL:-http://127.0.0.1:9090}/api/v1/status/tsdb\""]}}]}],"retired_below":"0.1.16"},{"id":"pure-flasharray","name":"Pure Storage FlashArray (Purity//FA REST)","version":"0.1.13","description":"Read-only access to a Pure Storage FlashArray over its Purity//FA REST API 2.x: array identity / capacity / performance, per-volume, per-host and per-interface performance with an optional history window, alerts, controller and hardware / drive health, volumes and per-volume space, protection groups, snapshots and membership, the host -> volume -> LUN connection map, host and target-port identities, per-controller network interface state, and replication / array-connection status. Drives a remote array via curl; every call is a GET.","vendor":"emisar","homepage":"https://emisar.dev/packs/pure-flasharray","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/pure-flasharray","content_hash":"sha256:cd0fb996623972781ab94b5c441ad8ea6f14eec7410fe361e270c1c0b6484a97","tarball_url":"https://registry.emisar.dev/v1/packs/pure-flasharray/0.1.13/cd0fb996623972781ab94b5c441ad8ea6f14eec7410fe361e270c1c0b6484a97/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Every action calls the FlashArray REST API 2.x at `$PURE_URL` via curl on the runner host. The array uses a two-step auth: the API token in `$PURE_API_TOKEN` is exchanged at /login for a short-lived session token, which is then sent on the read. Point `PURE_URL` at the array management endpoint and issue `PURE_API_TOKEN` for a readonly-role array user.","env":[{"name":"PURE_URL","description":"Array management endpoint — scheme + host[:port].","default":"https://192.168.1.1","example":"https://flasharray1.internal"},{"name":"PURE_API_TOKEN","description":"FlashArray API token for a readonly-role user; sent as the api-token header over curl stdin, never in argv or the audit log."},{"name":"PURE_INSECURE","description":"true to skip TLS verification of the array's self-signed certificate."}],"notes":["Any of `PURE_URL` / `PURE_API_TOKEN` / `PURE_INSECURE` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Every action is a read-only GET — none write, delete, or mutate array state.","Issue the token from a readonly-role array user (Settings -> Users) as defense-in-depth, so the credential itself cannot change anything even though the pack only ever issues GETs.","The session token auto-expires after ~30 min of inactivity; the script re-logins on every call, so there is no session to manage."],"verify":"pure.arrays"},"actions":[{"id":"pure.alerts","title":"GET /alerts","summary":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","description":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes, acknowledges, or clears alerts."],"args":[],"examples":[{"title":"All open alerts (by severity)","args":{}}],"search_terms":["array degraded","failed drive","storage alarms"]},{"id":"pure.array_connections","title":"GET /array-connections","summary":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","description":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Replication / connected-array status","args":{}}],"search_terms":[]},{"id":"pure.arrays","title":"GET /arrays","summary":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","description":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array identity and capacity","args":{}}],"search_terms":[]},{"id":"pure.arrays_performance","title":"GET /arrays/performance","summary":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","description":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a few dozen samples; 1s is the array's finest and is array-wide only.","validation":{"enum":["auto","1s","30s","5m","30m","2h","8h","24h"]}}],"examples":[{"title":"Latest array latency / IOPS / bandwidth","args":{}},{"title":"The last five minutes, second by second","args":{"resolution":"1s","window":"5m"}}],"search_terms":["storage slow","san slow"]},{"id":"pure.arrays_space","title":"GET /arrays/space","summary":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","description":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array capacity and data-reduction","args":{}}],"search_terms":["array full","out of space"]},{"id":"pure.connections","title":"GET /connections","summary":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","description":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Full host -> volume -> LUN map","args":{}}],"search_terms":["lun mapping","host cannot see lun"]},{"id":"pure.controllers","title":"GET /controllers","summary":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","description":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Controller mode / model / version / status","args":{}}],"search_terms":["controller failover"]},{"id":"pure.default_protection","title":"Show FlashArray default protection","summary":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","description":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /container-default-protections.","Read-only - never changes a container's default protection."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum containers in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Local array and pod defaults","args":{}}],"search_terms":[]},{"id":"pure.drives","title":"GET /drives","summary":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","description":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Flash / NVRAM module status","args":{}}],"search_terms":["failed drive","array degraded","disk failure"]},{"id":"pure.hardware","title":"GET /hardware","summary":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","description":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Chassis / PSU / fan / temperature health","args":{}}],"search_terms":["array degraded","failed drive","failed psu","fan failure","overheating"]},{"id":"pure.hosts","title":"GET /hosts","summary":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","description":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Host inventory (IQNs / WWNs / NQNs)","args":{}}],"search_terms":[]},{"id":"pure.hosts_performance","title":"GET /hosts/performance","summary":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","description":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per host.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated host names; empty covers every host.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per host per sample time, so a window fits fewer hosts. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every host's current IOPS and latency","args":{}},{"title":"One host's last hour","args":{"names":"app-node-3","window":"1h"}}],"search_terms":["which host is slow","server storage latency"]},{"id":"pure.network_interfaces","title":"GET /network-interfaces","summary":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","description":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Interface up/down state, speed, services","args":{}}],"search_terms":[]},{"id":"pure.network_interfaces_performance","title":"GET /network-interfaces/performance","summary":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","description":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per interface.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated interface names such as ct0.eth4; empty covers every interface.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per interface per sample time, so a window fits fewer interfaces. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Current throughput on every interface","args":{}},{"title":"One port's last six hours","args":{"names":"ct0.eth4","window":"6h"}}],"search_terms":["port saturated","target port traffic"]},{"id":"pure.pgroup_members","title":"List FlashArray protection-group members","summary":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","description":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the selected /protection-groups member endpoint.","Read-only - never adds or removes a protection-group member."],"args":[{"name":"member_type","type":"string","required":true,"description":"Protection-group member resource to list.","validation":{"enum":["volumes","hosts","host-groups"]}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum membership records in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Volume membership","args":{"member_type":"volumes"}}],"search_terms":[]},{"id":"pure.ports","title":"GET /ports","summary":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","description":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"iSCSI / FC / NVMe target port identities","args":{}}],"search_terms":[]},{"id":"pure.protection_groups","title":"List FlashArray protection groups","summary":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","description":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-groups.","Read-only - never creates, modifies, destroys, or eradicates a group."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum protection groups in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"First page of protection groups","args":{}}],"search_terms":[]},{"id":"pure.snapshots","title":"List FlashArray protection-group snapshots","summary":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","description":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-group-snapshots.","Read-only - never creates, destroys, or eradicates a snapshot."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Most recent snapshot page","args":{}}],"search_terms":[]},{"id":"pure.volumes","title":"GET /volumes","summary":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","description":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Volume inventory and provisioned size","args":{}}],"search_terms":[]},{"id":"pure.volumes_performance","title":"GET /volumes/performance","summary":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","description":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per volume.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated volume names; empty covers every volume.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per volume per sample time, so a window fits fewer volumes. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every volume's current latency and IOPS","args":{}},{"title":"One volume's last 24 hours","args":{"names":"prod-db-01","window":"24h"}}],"search_terms":["noisy neighbor","volume latency","which volume is slow"]},{"id":"pure.volumes_space","title":"GET /volumes/space","summary":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","description":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Per-volume used / snapshot / data-reduction","args":{}}],"search_terms":["volume full","lun full"]}],"previous_versions":[{"version":"0.1.12","content_hash":"sha256:24ba09a8e64bd2ee5b35163246ca7874d9161e4ac4c48837ac9f0f837b820f40","tarball_url":"https://registry.emisar.dev/v1/packs/pure-flasharray/0.1.12/24ba09a8e64bd2ee5b35163246ca7874d9161e4ac4c48837ac9f0f837b820f40/pack.tar.gz","actions":[{"id":"pure.alerts","title":"GET /alerts","summary":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","description":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes, acknowledges, or clears alerts."],"args":[],"examples":[{"title":"All open alerts (by severity)","args":{}}],"search_terms":["array degraded","failed drive","storage alarms"]},{"id":"pure.array_connections","title":"GET /array-connections","summary":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","description":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Replication / connected-array status","args":{}}],"search_terms":[]},{"id":"pure.arrays","title":"GET /arrays","summary":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","description":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array identity and capacity","args":{}}],"search_terms":[]},{"id":"pure.arrays_performance","title":"GET /arrays/performance","summary":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","description":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a few dozen samples; 1s is the array's finest and is array-wide only.","validation":{"enum":["auto","1s","30s","5m","30m","2h","8h","24h"]}}],"examples":[{"title":"Latest array latency / IOPS / bandwidth","args":{}},{"title":"The last five minutes, second by second","args":{"resolution":"1s","window":"5m"}}],"search_terms":["storage slow","san slow"]},{"id":"pure.arrays_space","title":"GET /arrays/space","summary":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","description":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array capacity and data-reduction","args":{}}],"search_terms":["array full","out of space"]},{"id":"pure.connections","title":"GET /connections","summary":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","description":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Full host -> volume -> LUN map","args":{}}],"search_terms":["lun mapping","host cannot see lun"]},{"id":"pure.controllers","title":"GET /controllers","summary":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","description":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Controller mode / model / version / status","args":{}}],"search_terms":["controller failover"]},{"id":"pure.default_protection","title":"Show FlashArray default protection","summary":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","description":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /container-default-protections.","Read-only - never changes a container's default protection."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum containers in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Local array and pod defaults","args":{}}],"search_terms":[]},{"id":"pure.drives","title":"GET /drives","summary":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","description":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Flash / NVRAM module status","args":{}}],"search_terms":["failed drive","array degraded","disk failure"]},{"id":"pure.hardware","title":"GET /hardware","summary":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","description":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Chassis / PSU / fan / temperature health","args":{}}],"search_terms":["array degraded","failed drive","failed psu","fan failure","overheating"]},{"id":"pure.hosts","title":"GET /hosts","summary":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","description":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Host inventory (IQNs / WWNs / NQNs)","args":{}}],"search_terms":[]},{"id":"pure.hosts_performance","title":"GET /hosts/performance","summary":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","description":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per host.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated host names; empty covers every host.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per host per sample time, so a window fits fewer hosts. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every host's current IOPS and latency","args":{}},{"title":"One host's last hour","args":{"names":"app-node-3","window":"1h"}}],"search_terms":["which host is slow","server storage latency"]},{"id":"pure.network_interfaces","title":"GET /network-interfaces","summary":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","description":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Interface up/down state, speed, services","args":{}}],"search_terms":[]},{"id":"pure.network_interfaces_performance","title":"GET /network-interfaces/performance","summary":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","description":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per interface.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated interface names such as ct0.eth4; empty covers every interface.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per interface per sample time, so a window fits fewer interfaces. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Current throughput on every interface","args":{}},{"title":"One port's last six hours","args":{"names":"ct0.eth4","window":"6h"}}],"search_terms":["port saturated","target port traffic"]},{"id":"pure.pgroup_members","title":"List FlashArray protection-group members","summary":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","description":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the selected /protection-groups member endpoint.","Read-only - never adds or removes a protection-group member."],"args":[{"name":"member_type","type":"string","required":true,"description":"Protection-group member resource to list.","validation":{"enum":["volumes","hosts","host-groups"]}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum membership records in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Volume membership","args":{"member_type":"volumes"}}],"search_terms":[]},{"id":"pure.ports","title":"GET /ports","summary":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","description":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"iSCSI / FC / NVMe target port identities","args":{}}],"search_terms":[]},{"id":"pure.protection_groups","title":"List FlashArray protection groups","summary":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","description":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-groups.","Read-only - never creates, modifies, destroys, or eradicates a group."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum protection groups in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"First page of protection groups","args":{}}],"search_terms":[]},{"id":"pure.snapshots","title":"List FlashArray protection-group snapshots","summary":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","description":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-group-snapshots.","Read-only - never creates, destroys, or eradicates a snapshot."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Most recent snapshot page","args":{}}],"search_terms":[]},{"id":"pure.volumes","title":"GET /volumes","summary":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","description":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Volume inventory and provisioned size","args":{}}],"search_terms":[]},{"id":"pure.volumes_performance","title":"GET /volumes/performance","summary":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","description":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per volume.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated volume names; empty covers every volume.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per volume per sample time, so a window fits fewer volumes. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every volume's current latency and IOPS","args":{}},{"title":"One volume's last 24 hours","args":{"names":"prod-db-01","window":"24h"}}],"search_terms":["noisy neighbor","volume latency","which volume is slow"]},{"id":"pure.volumes_space","title":"GET /volumes/space","summary":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","description":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Per-volume used / snapshot / data-reduction","args":{}}],"search_terms":["volume full","lun full"]}]},{"version":"0.1.10","content_hash":"sha256:476b58d1f723af469678569e9a89b02f3b132407fcc8f86199b11a3b08e58559","tarball_url":"https://registry.emisar.dev/v1/packs/pure-flasharray/0.1.10/476b58d1f723af469678569e9a89b02f3b132407fcc8f86199b11a3b08e58559/pack.tar.gz","actions":[{"id":"pure.alerts","title":"GET /alerts","summary":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","description":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes, acknowledges, or clears alerts."],"args":[],"examples":[{"title":"All open alerts (by severity)","args":{}}],"search_terms":["array degraded","failed drive","storage alarms"]},{"id":"pure.array_connections","title":"GET /array-connections","summary":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","description":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Replication / connected-array status","args":{}}],"search_terms":[]},{"id":"pure.arrays","title":"GET /arrays","summary":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","description":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array identity and capacity","args":{}}],"search_terms":[]},{"id":"pure.arrays_performance","title":"GET /arrays/performance","summary":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","description":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a few dozen samples; 1s is the array's finest and is array-wide only.","validation":{"enum":["auto","1s","30s","5m","30m","2h","8h","24h"]}}],"examples":[{"title":"Latest array latency / IOPS / bandwidth","args":{}},{"title":"The last five minutes, second by second","args":{"resolution":"1s","window":"5m"}}],"search_terms":["storage slow","san slow"]},{"id":"pure.arrays_space","title":"GET /arrays/space","summary":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","description":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array capacity and data-reduction","args":{}}],"search_terms":["array full","out of space"]},{"id":"pure.connections","title":"GET /connections","summary":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","description":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Full host -> volume -> LUN map","args":{}}],"search_terms":["lun mapping","host cannot see lun"]},{"id":"pure.controllers","title":"GET /controllers","summary":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","description":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Controller mode / model / version / status","args":{}}],"search_terms":["controller failover"]},{"id":"pure.default_protection","title":"Show FlashArray default protection","summary":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","description":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /container-default-protections.","Read-only - never changes a container's default protection."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum containers in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Local array and pod defaults","args":{}}],"search_terms":[]},{"id":"pure.drives","title":"GET /drives","summary":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","description":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Flash / NVRAM module status","args":{}}],"search_terms":["failed drive","array degraded","disk failure"]},{"id":"pure.hardware","title":"GET /hardware","summary":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","description":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Chassis / PSU / fan / temperature health","args":{}}],"search_terms":["array degraded","failed drive","failed psu","fan failure","overheating"]},{"id":"pure.hosts","title":"GET /hosts","summary":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","description":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Host inventory (IQNs / WWNs / NQNs)","args":{}}],"search_terms":[]},{"id":"pure.hosts_performance","title":"GET /hosts/performance","summary":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","description":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per host.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated host names; empty covers every host.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per host per sample time, so a window fits fewer hosts. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every host's current IOPS and latency","args":{}},{"title":"One host's last hour","args":{"names":"app-node-3","window":"1h"}}],"search_terms":["which host is slow","server storage latency"]},{"id":"pure.network_interfaces","title":"GET /network-interfaces","summary":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","description":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Interface up/down state, speed, services","args":{}}],"search_terms":[]},{"id":"pure.network_interfaces_performance","title":"GET /network-interfaces/performance","summary":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","description":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per interface.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated interface names such as ct0.eth4; empty covers every interface.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per interface per sample time, so a window fits fewer interfaces. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Current throughput on every interface","args":{}},{"title":"One port's last six hours","args":{"names":"ct0.eth4","window":"6h"}}],"search_terms":["port saturated","target port traffic"]},{"id":"pure.pgroup_members","title":"List FlashArray protection-group members","summary":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","description":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the selected /protection-groups member endpoint.","Read-only - never adds or removes a protection-group member."],"args":[{"name":"member_type","type":"string","required":true,"description":"Protection-group member resource to list.","validation":{"enum":["volumes","hosts","host-groups"]}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum membership records in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Volume membership","args":{"member_type":"volumes"}}],"search_terms":[]},{"id":"pure.ports","title":"GET /ports","summary":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","description":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"iSCSI / FC / NVMe target port identities","args":{}}],"search_terms":[]},{"id":"pure.protection_groups","title":"List FlashArray protection groups","summary":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","description":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-groups.","Read-only - never creates, modifies, destroys, or eradicates a group."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum protection groups in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"First page of protection groups","args":{}}],"search_terms":[]},{"id":"pure.snapshots","title":"List FlashArray protection-group snapshots","summary":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","description":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-group-snapshots.","Read-only - never creates, destroys, or eradicates a snapshot."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque next_page_cursor from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Most recent snapshot page","args":{}}],"search_terms":[]},{"id":"pure.volumes","title":"GET /volumes","summary":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","description":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Volume inventory and provisioned size","args":{}}],"search_terms":[]},{"id":"pure.volumes_performance","title":"GET /volumes/performance","summary":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","description":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per volume.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated volume names; empty covers every volume.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per volume per sample time, so a window fits fewer volumes. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every volume's current latency and IOPS","args":{}},{"title":"One volume's last 24 hours","args":{"names":"prod-db-01","window":"24h"}}],"search_terms":["noisy neighbor","volume latency","which volume is slow"]},{"id":"pure.volumes_space","title":"GET /volumes/space","summary":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","description":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Per-volume used / snapshot / data-reduction","args":{}}],"search_terms":["volume full","lun full"]}]},{"version":"0.1.9","content_hash":"sha256:cdbe9eefa537f309ace0ba55e23ec11cc693dff4984590a58c31e842f40d2de6","tarball_url":"https://registry.emisar.dev/v1/packs/pure-flasharray/0.1.9/cdbe9eefa537f309ace0ba55e23ec11cc693dff4984590a58c31e842f40d2de6/pack.tar.gz","actions":[{"id":"pure.alerts","title":"GET /alerts","summary":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","description":"List open (unresolved) array alerts, filtered to state='open' — each with its severity (info / warning / critical), component, and summary. Use to answer \"what is the array complaining about right now?\". Returns {items:[...], more_items_remaining, ...}, one item per open alert.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes, acknowledges, or clears alerts."],"args":[],"examples":[{"title":"All open alerts (by severity)","args":{}}],"search_terms":["array degraded","failed drive","storage alarms"]},{"id":"pure.array_connections","title":"GET /array-connections","summary":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","description":"List connected-array / replication status — each peer array this array is connected to, the connection type (async / sync replication), and its status. Use to confirm replication peers are connected and healthy. Returns {items:[...], more_items_remaining, ...}, one item per connected array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Replication / connected-array status","args":{}}],"search_terms":[]},{"id":"pure.arrays","title":"GET /arrays","summary":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","description":"Show array identity and top-line health — array name, id, Purity//FA OS version, and the headline capacity fields. The starting point for \"which array is this and is it healthy?\". Returns {items:[...], more_items_remaining, ...}; one item per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array identity and capacity","args":{}}],"search_terms":[]},{"id":"pure.arrays_performance","title":"GET /arrays/performance","summary":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","description":"Show array-wide performance — read/write/mirrored latency, IOPS, and bandwidth, either the latest sample or a window of history. Use to answer \"is the array slow right now?\", and with a window \"was it slow when the incident started?\". Returns {items:[...], more_items_remaining, ...}, one item per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a few dozen samples; 1s is the array's finest and is array-wide only.","validation":{"enum":["auto","1s","30s","5m","30m","2h","8h","24h"]}}],"examples":[{"title":"Latest array latency / IOPS / bandwidth","args":{}},{"title":"The last five minutes, second by second","args":{"resolution":"1s","window":"5m"}}],"search_terms":["storage slow","san slow"]},{"id":"pure.arrays_space","title":"GET /arrays/space","summary":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","description":"Show array-wide space accounting — total and used capacity, plus the data reduction and thin-provisioning ratios behind it. Use to answer \"how full is the array and what is the effective reduction?\". Returns {items:[...], more_items_remaining, ...} with a space breakdown per array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Array capacity and data-reduction","args":{}}],"search_terms":["array full","out of space"]},{"id":"pure.connections","title":"GET /connections","summary":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","description":"Show the host -> volume -> LUN map: every connection between a host (or host group) and a volume, with the LUN the volume is presented at. This is the authoritative answer to \"which host sees which volume, at which LUN?\" — the first stop for any \"my server can't see its LUN\" or \"is this volume even mapped?\" question. Returns {items:[...], more_items_remaining, ...}, one item per host/volume connection; can be large on a busy array.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Full host -> volume -> LUN map","args":{}}],"search_terms":["lun mapping","host cannot see lun"]},{"id":"pure.controllers","title":"GET /controllers","summary":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","description":"List the array's controllers — for each, its mode (primary / secondary), model, running Purity//FA version, and status. Use to confirm the HA pair is healthy and which controller is primary. Returns {items:[...], more_items_remaining, ...}, one item per controller.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Controller mode / model / version / status","args":{}}],"search_terms":["controller failover"]},{"id":"pure.default_protection","title":"Show FlashArray default protection","summary":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","description":"Show the protection groups automatically applied to newly created volumes on the local array and its pods. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /container-default-protections.","Read-only - never changes a container's default protection."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum containers in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation_token from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Local array and pod defaults","args":{}}],"search_terms":[]},{"id":"pure.drives","title":"GET /drives","summary":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","description":"List flash and NVRAM modules — for each drive, its type, capacity, and status (healthy / unhealthy / evacuating / unused). Use to find a failed or evacuating module. Returns {items:[...], more_items_remaining, ...}, one item per drive.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Flash / NVRAM module status","args":{}}],"search_terms":["failed drive","array degraded","disk failure"]},{"id":"pure.hardware","title":"GET /hardware","summary":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","description":"Show physical component health — chassis, power supplies, fans, temperature sensors, and other hardware items, each with its status and (where applicable) reading. Use to find a failed PSU/fan or a hot sensor. Returns {items:[...], more_items_remaining, ...}, one item per component.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Chassis / PSU / fan / temperature health","args":{}}],"search_terms":["array degraded","failed drive","failed psu","fan failure","overheating"]},{"id":"pure.hosts","title":"GET /hosts","summary":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","description":"List the host inventory — each host object and the initiator identities registered to it: iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs. Use to confirm an initiator is registered to the expected host. Returns {items:[...], more_items_remaining, ...}, one item per host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Host inventory (IQNs / WWNs / NQNs)","args":{}}],"search_terms":[]},{"id":"pure.hosts_performance","title":"GET /hosts/performance","summary":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","description":"Show per-host performance — read/write IOPS, bandwidth, and latency as seen by each host object, either the latest sample or a window of history. Use to answer \"which server is generating the load?\" and to compare what a host reports with what the array served it. Returns {items:[...], more_items_remaining, ...}, one item per host per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per host.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated host names; empty covers every host.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per host per sample time, so a window fits fewer hosts. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every host's current IOPS and latency","args":{}},{"title":"One host's last hour","args":{"names":"app-node-3","window":"1h"}}],"search_terms":["which host is slow","server storage latency"]},{"id":"pure.network_interfaces","title":"GET /network-interfaces","summary":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","description":"List per-controller network interfaces — each interface's enabled / up-or-down state, speed, address, and the services it carries (management, iSCSI, replication, NVMe-oF). Use this to answer \"is the target port up?\" before chasing a host-side path problem. Returns {items:[...], more_items_remaining, ...}, one item per interface.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Interface up/down state, speed, services","args":{}}],"search_terms":[]},{"id":"pure.network_interfaces_performance","title":"GET /network-interfaces/performance","summary":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","description":"Show per-interface throughput — received and transmitted bytes and packets per second on each array network interface, either the latest sample or a window of history. Use to answer \"is one target port carrying all the traffic?\" or to confirm a port went quiet when a path failed. Returns {items:[...], more_items_remaining, ...}, one item per interface per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per interface.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated interface names such as ct0.eth4; empty covers every interface.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per interface per sample time, so a window fits fewer interfaces. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Current throughput on every interface","args":{}},{"title":"One port's last six hours","args":{"names":"ct0.eth4","window":"6h"}}],"search_terms":["port saturated","target port traffic"]},{"id":"pure.pgroup_members","title":"List FlashArray protection-group members","summary":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","description":"List volume, host, or host-group membership in protection groups. Each item identifies the group and member; results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the selected /protection-groups member endpoint.","Read-only - never adds or removes a protection-group member."],"args":[{"name":"member_type","type":"string","required":true,"description":"Protection-group member resource to list.","validation":{"enum":["volumes","hosts","host-groups"]}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum membership records in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation_token from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Volume membership","args":{"member_type":"volumes"}}],"search_terms":[]},{"id":"pure.ports","title":"GET /ports","summary":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","description":"List target-port identities — the array-side iSCSI IQNs, Fibre Channel WWNs, and NVMe NQNs, with iSCSI portal IPs where applicable. Use to learn what addresses a host should be connecting to. Returns {items:[...], more_items_remaining, ...}, one item per target port.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"iSCSI / FC / NVMe target port identities","args":{}}],"search_terms":[]},{"id":"pure.protection_groups","title":"List FlashArray protection groups","summary":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","description":"List protection groups and their snapshot, replication, and retention configuration. Results are bounded to one page and include the API cursor when another page is available.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-groups.","Read-only - never creates, modifies, destroys, or eradicates a group."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum protection groups in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation_token from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"First page of protection groups","args":{}}],"search_terms":[]},{"id":"pure.snapshots","title":"List FlashArray protection-group snapshots","summary":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","description":"List protection-group snapshots, including creation time, source group, destroyed state, and retention time. Results are bounded to one page.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to /protection-group-snapshots.","Read-only - never creates, destroys, or eradicates a snapshot."],"args":[{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum snapshots in this page.","validation":{"min":1,"max":1000}},{"name":"page_cursor","type":"string","required":false,"default":"","description":"Opaque continuation_token from a prior result.","validation":{"pattern":"^[A-Za-z0-9._~+/=-]*$","max_length":2048}}],"examples":[{"title":"Most recent snapshot page","args":{}}],"search_terms":[]},{"id":"pure.volumes","title":"GET /volumes","summary":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","description":"List the volume inventory — each volume's name, id, provisioned (virtual) size, and whether it is destroyed / pending eradication. Use to confirm a volume exists and its size. Returns {items:[...], more_items_remaining, ...}, one item per volume; can be large on arrays with many volumes.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Volume inventory and provisioned size","args":{}}],"search_terms":[]},{"id":"pure.volumes_performance","title":"GET /volumes/performance","summary":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","description":"Show per-volume performance — read/write/mirrored IOPS, bandwidth, and latency for each volume, either the latest sample or a window of history. Use after pure.arrays_performance says the array is slow, to answer \"which volume is driving it?\" by comparing the volumes in the page. Returns {items:[...], more_items_remaining, ...}, one item per volume per sample.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[{"name":"window","type":"string","required":false,"default":"latest","description":"History window ending now; latest returns only the newest sample.","validation":{"enum":["latest","5m","1h","6h","24h","7d"]}},{"name":"resolution","type":"string","required":false,"default":"auto","description":"Interval between samples. auto picks one that keeps a window to a dozen or so samples per volume.","validation":{"enum":["auto","30s","5m","30m","2h","8h","24h"]}},{"name":"names","type":"string","required":false,"default":"","description":"Comma-separated volume names; empty covers every volume.","validation":{"pattern":"^[A-Za-z0-9._:/-]*(,[A-Za-z0-9._:/-]+)*$","max_length":512}},{"name":"limit","type":"integer","required":false,"default":200,"description":"Maximum samples in this page — one per volume per sample time, so a window fits fewer volumes. more_items_remaining reports a full page.","validation":{"min":1,"max":1000}}],"examples":[{"title":"Every volume's current latency and IOPS","args":{}},{"title":"One volume's last 24 hours","args":{"names":"prod-db-01","window":"24h"}}],"search_terms":["noisy neighbor","volume latency","which volume is slow"]},{"id":"pure.volumes_space","title":"GET /volumes/space","summary":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","description":"Show per-volume space accounting — for each volume, the physical space used by its unique data and by snapshots, plus its data-reduction and total-reduction ratios. Use to find which volumes consume the most capacity. Returns {items:[...], more_items_remaining, ...}, one item per volume.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the FlashArray REST API.","Read-only — never writes or mutates array state."],"args":[],"examples":[{"title":"Per-volume used / snapshot / data-reduction","args":{}}],"search_terms":["volume full","lun full"]}]}]},{"id":"python-app","name":"Python application runtime","version":"0.1.11","description":"Inspect a Python deployment — interpreter + venv state, pip inventory + freeze, dependency conflicts, outdated packages, sys.path. Read-only. Most actions act on the venv at PY_VENV env var (default /opt/app/venv).","vendor":"emisar","homepage":"https://emisar.dev/packs/python-app","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/python-app","content_hash":"sha256:2ac36827af136cc80529fa1b36eb8560ae820a56d40318f82722fde2af887e24","tarball_url":"https://registry.emisar.dev/v1/packs/python-app/0.1.11/2ac36827af136cc80529fa1b36eb8560ae820a56d40318f82722fde2af887e24/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Inspects a local Python deployment on the runner host — interpreter, venv, and pip state — no credentials needed.","env":[{"name":"PY_VENV","description":"Path to the application's virtualenv; the venv-scoped actions run its bin/python and bin/pip. Optional; defaults to `/opt/app/venv`. Add it to the runner's `inherit_env` if you override it.","default":"/opt/app/venv"}],"notes":["System actions use `/usr/bin/python3`; venv actions use `PY_VENV`."],"host_access":[{"actions":["py.venv_python_version","py.pip_list","py.pip_freeze","py.pip_show","py.pip_check","py.pip_outdated","py.sys_path","py.site_packages_du","py.pip_cache_info"],"requirement":"Read a virtual environment owned by another operating-system user.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-python-app-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root and can read application code, installed packages, and any credentials stored beside the virtual environment."}]}],"verify":"py.python_version_system"},"actions":[{"id":"py.pip_cache_info","title":"$PY_VENV/bin/pip cache info","summary":"Show pip cache size + location.","description":"Show pip cache size + location.","kind":"exec","risk":"low","side_effects":["One pip cache call.","Read-only."],"args":[],"examples":[{"title":"Cache info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" cache info"]}},{"id":"py.pip_check","title":"$PY_VENV/bin/pip check","summary":"Check for dependency conflicts. Empty output means clean.","description":"Check for dependency conflicts. Empty output means clean.","kind":"exec","risk":"low","side_effects":["One pip check call.","Read-only."],"args":[],"examples":[{"title":"Dep conflicts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" check"]}},{"id":"py.pip_freeze","title":"$PY_VENV/bin/pip freeze","summary":"Dump installed packages in requirements format.","description":"Dump installed packages in requirements format.","kind":"exec","risk":"low","side_effects":["One pip freeze call.","Read-only."],"args":[],"examples":[{"title":"Freeze","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" freeze"]}},{"id":"py.pip_list","title":"$PY_VENV/bin/pip list","summary":"List installed packages with versions.","description":"List installed packages with versions.","kind":"exec","risk":"low","side_effects":["One pip list call.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --format=json"]}},{"id":"py.pip_outdated","title":"$PY_VENV/bin/pip list --outdated","summary":"List packages with newer versions available.","description":"List packages with newer versions available.","kind":"exec","risk":"low","side_effects":["Queries PyPI (or configured index) for latest versions.","Read-only."],"args":[],"examples":[{"title":"Outdated","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --outdated --format=json"]}},{"id":"py.pip_show","title":"$PY_VENV/bin/pip show <pkg>","summary":"Show details for one package (version, deps, location).","description":"Show details for one package (version, deps, location).","kind":"exec","risk":"low","side_effects":["One pip show call.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One package","args":{"package":"django"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" show -- \"$1\"","emisar","{{ args.package }}"]}},{"id":"py.python_version_system","title":"python3 --version (system)","summary":"Show the system python interpreter version.","description":"Show the system python interpreter version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"System python","args":{}}],"search_terms":[],"command":{"binary":"python3","argv":["--version"]}},{"id":"py.site_packages_du","title":"du -sh site-packages/*","summary":"Show disk usage per installed package — find bloated installs.","description":"Show disk usage per installed package — find bloated installs.","kind":"exec","risk":"low","side_effects":["One file-system traversal of the venv's site-packages.","Read-only."],"args":[],"examples":[{"title":"Top packages by disk","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","V=${PY_VENV:-/opt/app/venv}\nSP=$(\"$V/bin/python\" -c 'import site; print(site.getsitepackages()[0])') || { echo \"cannot resolve site-packages via $V/bin/python\" >&2; exit 1; }\n[ -n \"$SP\" ] && [ -d \"$SP\" ] || { echo \"site-packages is not a readable directory: $SP\" >&2; exit 1; }\ndu -sh \"$SP\"/* 2>/dev/null | sort -rh | head -50\n"]}},{"id":"py.sys_path","title":"python -c 'import sys; print(sys.path)'","summary":"Show the effective sys.path for the venv interpreter.","description":"Show the effective sys.path for the venv interpreter.","kind":"exec","risk":"low","side_effects":["One forked python process.","Read-only."],"args":[],"examples":[{"title":"sys.path","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" -c 'import sys; [print(p) for p in sys.path]'"]}},{"id":"py.venv_python_version","title":"$PY_VENV/bin/python --version","summary":"Show the interpreter version inside the configured venv.","description":"Show the interpreter version inside the configured venv.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Venv python","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" --version 2>&1"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:eec0441ba2d153a1613c76382bef67c8f6d557b07f9e47fb5bb0fb28f58f6629","tarball_url":"https://registry.emisar.dev/v1/packs/python-app/0.1.10/eec0441ba2d153a1613c76382bef67c8f6d557b07f9e47fb5bb0fb28f58f6629/pack.tar.gz","actions":[{"id":"py.pip_cache_info","title":"$PY_VENV/bin/pip cache info","summary":"Show pip cache size + location.","description":"Show pip cache size + location.","kind":"exec","risk":"low","side_effects":["One pip cache call.","Read-only."],"args":[],"examples":[{"title":"Cache info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" cache info"]}},{"id":"py.pip_check","title":"$PY_VENV/bin/pip check","summary":"Check for dependency conflicts. Empty output means clean.","description":"Check for dependency conflicts. Empty output means clean.","kind":"exec","risk":"low","side_effects":["One pip check call.","Read-only."],"args":[],"examples":[{"title":"Dep conflicts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" check"]}},{"id":"py.pip_freeze","title":"$PY_VENV/bin/pip freeze","summary":"Dump installed packages in requirements format.","description":"Dump installed packages in requirements format.","kind":"exec","risk":"low","side_effects":["One pip freeze call.","Read-only."],"args":[],"examples":[{"title":"Freeze","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" freeze"]}},{"id":"py.pip_list","title":"$PY_VENV/bin/pip list","summary":"List installed packages with versions.","description":"List installed packages with versions.","kind":"exec","risk":"low","side_effects":["One pip list call.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --format=json"]}},{"id":"py.pip_outdated","title":"$PY_VENV/bin/pip list --outdated","summary":"List packages with newer versions available.","description":"List packages with newer versions available.","kind":"exec","risk":"low","side_effects":["Queries PyPI (or configured index) for latest versions.","Read-only."],"args":[],"examples":[{"title":"Outdated","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --outdated --format=json"]}},{"id":"py.pip_show","title":"$PY_VENV/bin/pip show <pkg>","summary":"Show details for one package (version, deps, location).","description":"Show details for one package (version, deps, location).","kind":"exec","risk":"low","side_effects":["One pip show call.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One package","args":{"package":"django"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" show -- \"$1\"","emisar","{{ args.package }}"]}},{"id":"py.python_version_system","title":"python3 --version (system)","summary":"Show the system python interpreter version.","description":"Show the system python interpreter version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"System python","args":{}}],"search_terms":[],"command":{"binary":"python3","argv":["--version"]}},{"id":"py.site_packages_du","title":"du -sh site-packages/*","summary":"Show disk usage per installed package — find bloated installs.","description":"Show disk usage per installed package — find bloated installs.","kind":"exec","risk":"low","side_effects":["One file-system traversal of the venv's site-packages.","Read-only."],"args":[],"examples":[{"title":"Top packages by disk","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","V=${PY_VENV:-/opt/app/venv}\nSP=$(\"$V/bin/python\" -c 'import site; print(site.getsitepackages()[0])') || { echo \"cannot resolve site-packages via $V/bin/python\" >&2; exit 1; }\n[ -n \"$SP\" ] && [ -d \"$SP\" ] || { echo \"site-packages is not a readable directory: $SP\" >&2; exit 1; }\ndu -sh \"$SP\"/* 2>/dev/null | sort -rh | head -50\n"]}},{"id":"py.sys_path","title":"python -c 'import sys; print(sys.path)'","summary":"Show the effective sys.path for the venv interpreter.","description":"Show the effective sys.path for the venv interpreter.","kind":"exec","risk":"low","side_effects":["One forked python process.","Read-only."],"args":[],"examples":[{"title":"sys.path","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" -c 'import sys; [print(p) for p in sys.path]'"]}},{"id":"py.venv_python_version","title":"$PY_VENV/bin/python --version","summary":"Show the interpreter version inside the configured venv.","description":"Show the interpreter version inside the configured venv.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Venv python","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" --version 2>&1"]}}]},{"version":"0.1.7","content_hash":"sha256:fa00edbdb6035fbfc0df6e7ab9d4603a3c80599619ee6df4088c2fe4c22e934f","tarball_url":"https://registry.emisar.dev/v1/packs/python-app/0.1.7/fa00edbdb6035fbfc0df6e7ab9d4603a3c80599619ee6df4088c2fe4c22e934f/pack.tar.gz","actions":[{"id":"py.pip_cache_info","title":"$PY_VENV/bin/pip cache info","summary":"Show pip cache size + location.","description":"Show pip cache size + location.","kind":"exec","risk":"low","side_effects":["One pip cache call.","Read-only."],"args":[],"examples":[{"title":"Cache info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" cache info"]}},{"id":"py.pip_check","title":"$PY_VENV/bin/pip check","summary":"Check for dependency conflicts. Empty output means clean.","description":"Check for dependency conflicts. Empty output means clean.","kind":"exec","risk":"low","side_effects":["One pip check call.","Read-only."],"args":[],"examples":[{"title":"Dep conflicts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" check"]}},{"id":"py.pip_freeze","title":"$PY_VENV/bin/pip freeze","summary":"Dump installed packages in requirements format.","description":"Dump installed packages in requirements format.","kind":"exec","risk":"low","side_effects":["One pip freeze call.","Read-only."],"args":[],"examples":[{"title":"Freeze","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" freeze"]}},{"id":"py.pip_list","title":"$PY_VENV/bin/pip list","summary":"List installed packages with versions.","description":"List installed packages with versions.","kind":"exec","risk":"low","side_effects":["One pip list call.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --format=json"]}},{"id":"py.pip_outdated","title":"$PY_VENV/bin/pip list --outdated","summary":"List packages with newer versions available.","description":"List packages with newer versions available.","kind":"exec","risk":"low","side_effects":["Queries PyPI (or configured index) for latest versions.","Read-only."],"args":[],"examples":[{"title":"Outdated","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --outdated --format=json"]}},{"id":"py.pip_show","title":"$PY_VENV/bin/pip show <pkg>","summary":"Show details for one package (version, deps, location).","description":"Show details for one package (version, deps, location).","kind":"exec","risk":"low","side_effects":["One pip show call.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One package","args":{"package":"django"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" show -- \"$1\"","emisar","{{ args.package }}"]}},{"id":"py.python_version_system","title":"python3 --version (system)","summary":"Show the system python interpreter version.","description":"Show the system python interpreter version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"System python","args":{}}],"search_terms":[],"command":{"binary":"python3","argv":["--version"]}},{"id":"py.site_packages_du","title":"du -sh site-packages/*","summary":"Show disk usage per installed package — find bloated installs.","description":"Show disk usage per installed package — find bloated installs.","kind":"exec","risk":"low","side_effects":["One file-system traversal of the venv's site-packages.","Read-only."],"args":[],"examples":[{"title":"Top packages by disk","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","V=${PY_VENV:-/opt/app/venv}\nSP=$(\"$V/bin/python\" -c 'import site; print(site.getsitepackages()[0])') || { echo \"cannot resolve site-packages via $V/bin/python\" >&2; exit 1; }\n[ -n \"$SP\" ] && [ -d \"$SP\" ] || { echo \"site-packages is not a readable directory: $SP\" >&2; exit 1; }\ndu -sh \"$SP\"/* 2>/dev/null | sort -rh | head -50\n"]}},{"id":"py.sys_path","title":"python -c 'import sys; print(sys.path)'","summary":"Show the effective sys.path for the venv interpreter.","description":"Show the effective sys.path for the venv interpreter.","kind":"exec","risk":"low","side_effects":["One forked python process.","Read-only."],"args":[],"examples":[{"title":"sys.path","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" -c 'import sys; [print(p) for p in sys.path]'"]}},{"id":"py.venv_python_version","title":"$PY_VENV/bin/python --version","summary":"Show the interpreter version inside the configured venv.","description":"Show the interpreter version inside the configured venv.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Venv python","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" --version 2>&1"]}}]},{"version":"0.1.6","content_hash":"sha256:788b1d57be75b4fdbf26d8654cbb864969c31f44aee6be62b5d05fcd22ec5c72","tarball_url":"https://registry.emisar.dev/v1/packs/python-app/0.1.6/788b1d57be75b4fdbf26d8654cbb864969c31f44aee6be62b5d05fcd22ec5c72/pack.tar.gz","actions":[{"id":"py.pip_cache_info","title":"$PY_VENV/bin/pip cache info","summary":"Show pip cache size + location.","description":"Show pip cache size + location.","kind":"exec","risk":"low","side_effects":["One pip cache call.","Read-only."],"args":[],"examples":[{"title":"Cache info","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" cache info"]}},{"id":"py.pip_check","title":"$PY_VENV/bin/pip check","summary":"Check for dependency conflicts. Empty output means clean.","description":"Check for dependency conflicts. Empty output means clean.","kind":"exec","risk":"low","side_effects":["One pip check call.","Read-only."],"args":[],"examples":[{"title":"Dep conflicts","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" check"]}},{"id":"py.pip_freeze","title":"$PY_VENV/bin/pip freeze","summary":"Dump installed packages in requirements format.","description":"Dump installed packages in requirements format.","kind":"exec","risk":"low","side_effects":["One pip freeze call.","Read-only."],"args":[],"examples":[{"title":"Freeze","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" freeze"]}},{"id":"py.pip_list","title":"$PY_VENV/bin/pip list","summary":"List installed packages with versions.","description":"List installed packages with versions.","kind":"exec","risk":"low","side_effects":["One pip list call.","Read-only."],"args":[],"examples":[{"title":"All packages","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --format=json"]}},{"id":"py.pip_outdated","title":"$PY_VENV/bin/pip list --outdated","summary":"List packages with newer versions available.","description":"List packages with newer versions available.","kind":"exec","risk":"low","side_effects":["Queries PyPI (or configured index) for latest versions.","Read-only."],"args":[],"examples":[{"title":"Outdated","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" list --outdated --format=json"]}},{"id":"py.pip_show","title":"$PY_VENV/bin/pip show <pkg>","summary":"Show details for one package (version, deps, location).","description":"Show details for one package (version, deps, location).","kind":"exec","risk":"low","side_effects":["One pip show call.","Read-only."],"args":[{"name":"package","type":"string","required":true,"description":"Package name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"One package","args":{"package":"django"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/pip\" show -- \"$1\"","emisar","{{ args.package }}"]}},{"id":"py.python_version_system","title":"python3 --version (system)","summary":"Show the system python interpreter version.","description":"Show the system python interpreter version.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"System python","args":{}}],"search_terms":[],"command":{"binary":"python3","argv":["--version"]}},{"id":"py.site_packages_du","title":"du -sh site-packages/*","summary":"Show disk usage per installed package — find bloated installs.","description":"Show disk usage per installed package — find bloated installs.","kind":"exec","risk":"low","side_effects":["One file-system traversal of the venv's site-packages.","Read-only."],"args":[],"examples":[{"title":"Top packages by disk","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","V=${PY_VENV:-/opt/app/venv}; SP=$(\"$V/bin/python\" -c 'import site; print(site.getsitepackages()[0])'); du -sh \"$SP\"/* 2>/dev/null | sort -rh | head -50"]}},{"id":"py.sys_path","title":"python -c 'import sys; print(sys.path)'","summary":"Show the effective sys.path for the venv interpreter.","description":"Show the effective sys.path for the venv interpreter.","kind":"exec","risk":"low","side_effects":["One forked python process.","Read-only."],"args":[],"examples":[{"title":"sys.path","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" -c 'import sys; [print(p) for p in sys.path]'"]}},{"id":"py.venv_python_version","title":"$PY_VENV/bin/python --version","summary":"Show the interpreter version inside the configured venv.","description":"Show the interpreter version inside the configured venv.","kind":"exec","risk":"low","side_effects":["One forked process.","Read-only."],"args":[],"examples":[{"title":"Venv python","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","\"${PY_VENV:-/opt/app/venv}/bin/python\" --version 2>&1"]}}]}]},{"id":"rabbitmq","name":"RabbitMQ operations","version":"0.1.15","description":"Cluster, queue, exchange, binding, connection, channel, and consumer inventory plus narrow operator actions (purge_queue, set_policy, force_close_connection). Uses rabbitmqctl + rabbitmqadmin on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/rabbitmq","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/rabbitmq","content_hash":"sha256:59a73416107c807655d45db80dc60675cd7ea54d79b5aee965e5ee37374a1c74","tarball_url":"https://registry.emisar.dev/v1/packs/rabbitmq/0.1.15/59a73416107c807655d45db80dc60675cd7ea54d79b5aee965e5ee37374a1c74/pack.tar.gz","requires":{"os":["linux"],"binaries":["rabbitmqctl"]},"detect":{"binaries":["rabbitmqctl"],"processes":[],"ports":[5672,15672]},"setup":{"summary":"rabbitmqctl and rabbitmq-diagnostics talk to the RabbitMQ node on the same host and authenticate with the Erlang cookie, not a username or URL. No connection env vars — provisioning is about running as the right user.","notes":["These tools target the local node only. To manage a remote node you would need -n <node>, which these actions do not set."],"host_access":[{"actions":["rmq.cluster_status","rmq.node_health_check","rmq.list_nodes","rmq.list_vhosts","rmq.list_users","rmq.list_policies","rmq.list_parameters","rmq.list_queues","rmq.list_exchanges","rmq.list_bindings","rmq.list_connections","rmq.list_channels","rmq.list_consumers","rmq.purge_queue","rmq.close_connection","rmq.sync_queue","rmq.start_app","rmq.stop_app"],"requirement":"Read RabbitMQ's Erlang cookie and act as a local node administrator.","recipes":[{"name":"Run the Emisar service as root with RabbitMQ's live cookie","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-rabbitmq-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root","sudo env HOME=/var/lib/rabbitmq rabbitmq-diagnostics -q ping"],"impact":"Every Emisar action on this runner executes as root. Root can use the live Erlang cookie selected by the pack to administer the local node, including operations outside this pack."}]}],"verify":"rmq.node_health_check"},"actions":[{"id":"rmq.close_connection","title":"rabbitmqctl close_connection","summary":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","description":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","kind":"exec","risk":"high","side_effects":["Connection is dropped with the given reason.","In-flight unacked messages on its channels go back to the queue."],"args":[{"name":"pid","type":"string","required":true,"description":"Connection PID (from list_connections).","validation":{"pattern":"^<[A-Za-z0-9@._-]{1,255}>$"}},{"name":"note","type":"string","required":false,"default":"Closed by operator","description":"Explanation recorded with the connection close.","validation":{"pattern":"^[A-Za-z0-9].{0,254}$"}}],"examples":[{"title":"Drop a stuck conn","args":{"pid":"<rabbit@host.1.123.0>"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["close_connection","{{ args.pid }}","{{ args.note }}"]}},{"id":"rmq.cluster_status","title":"rabbitmqctl cluster_status","summary":"Show cluster summary: nodes, alarms, partitions.","description":"Show cluster summary: nodes, alarms, partitions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Cluster status","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_bindings","title":"rabbitmqctl list_bindings","summary":"List all bindings between exchanges and queues.","description":"List all bindings between exchanges and queues.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Bindings","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_bindings"]}},{"id":"rmq.list_channels","title":"rabbitmqctl list_channels","summary":"List all open channels with consumer + prefetch + ack stats.","description":"List all open channels with consumer + prefetch + ack stats.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Channels","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_channels","pid","connection","consumer_count","messages_unacknowledged","prefetch_count"]}},{"id":"rmq.list_connections","title":"rabbitmqctl list_connections","summary":"List all open AMQP connections with client + user + channels.","description":"List all open AMQP connections with client + user + channels.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Connections","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_connections","pid","user","peer_host","peer_port","channels","state"]}},{"id":"rmq.list_consumers","title":"rabbitmqctl list_consumers","summary":"List all active consumers + their queue + ack-mode + prefetch.","description":"List all active consumers + their queue + ack-mode + prefetch.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Consumers","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_consumers"]}},{"id":"rmq.list_exchanges","title":"rabbitmqctl list_exchanges","summary":"List all exchanges with type + durability.","description":"List all exchanges with type + durability.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Exchanges","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_exchanges","name","type","durable"]}},{"id":"rmq.list_nodes","title":"Known cluster nodes","summary":"List all known cluster nodes.","description":"List all known cluster nodes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_parameters","title":"rabbitmqctl list_parameters","summary":"List runtime parameters (federation upstreams, shovel definitions, etc).","description":"List runtime parameters (federation upstreams, shovel definitions, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Parameters","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_parameters"]}},{"id":"rmq.list_policies","title":"rabbitmqctl list_policies","summary":"List all set policies (HA, federation, shovel, etc).","description":"List all set policies (HA, federation, shovel, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_policies"]}},{"id":"rmq.list_queues","title":"rabbitmqctl list_queues","summary":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","description":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Queue stats","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_queues","name","messages_ready","messages_unacknowledged","consumers","memory"]}},{"id":"rmq.list_users","title":"rabbitmqctl list_users","summary":"List all users + tags.","description":"List all users + tags.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Users","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_users"]}},{"id":"rmq.list_vhosts","title":"rabbitmqctl list_vhosts","summary":"List all virtual hosts.","description":"List all virtual hosts.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_vhosts"]}},{"id":"rmq.node_health_check","title":"rabbitmq-diagnostics check_running","summary":"Check health — confirms the local node is running and reachable.","description":"Check health — confirms the local node is running and reachable.","kind":"exec","risk":"low","side_effects":["One diagnostics call.","Read-only."],"args":[],"examples":[{"title":"Node health","args":{}}],"search_terms":[],"command":{"binary":"rabbitmq-diagnostics","argv":["check_running"]}},{"id":"rmq.purge_queue","title":"rabbitmqctl purge_queue","summary":"Drop every message in one queue. Unprocessed messages are lost.","description":"Drop every message in one queue. Unprocessed messages are lost.","kind":"exec","risk":"critical","side_effects":["All messages in the queue (including unacked-in-flight) are deleted."],"args":[{"name":"vhost","type":"string","required":true,"description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}},{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,254}$"}}],"examples":[{"title":"Purge dead-letter queue","args":{"queue":"dead-letters","vhost":"/"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["purge_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}},{"id":"rmq.start_app","title":"rabbitmqctl start_app","summary":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","description":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","kind":"exec","risk":"medium","side_effects":["RabbitMQ app accepts client connections again.","Queues and exchanges from disk become available."],"args":[],"examples":[{"title":"Start the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["start_app"]}},{"id":"rmq.stop_app","title":"rabbitmqctl stop_app","summary":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","description":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","kind":"exec","risk":"high","side_effects":["RabbitMQ app stops; clients disconnect.","Erlang node keeps running.","Producers fail; consumers reconnect when start_app runs."],"args":[],"examples":[{"title":"Stop the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["stop_app"]}},{"id":"rmq.sync_queue","title":"rabbitmqctl sync_queue","summary":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","description":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","kind":"exec","risk":"medium","side_effects":["Mirror catches up with the master.","I/O bandwidth used by sync.","Producers/consumers unaffected (small latency hit possible)."],"args":[{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_:./][a-zA-Z0-9_:.\\-/]{0,255}$"}},{"name":"vhost","type":"string","required":false,"default":"/","description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-/]{1,128}$"}}],"examples":[{"title":"Sync orders queue","args":{"queue":"orders"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["sync_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}}],"previous_versions":[{"version":"0.1.14","content_hash":"sha256:03e0dc5ddbf0c1ee6515ce8f793fae9d39980eb130209fcc6576daa084308edf","tarball_url":"https://registry.emisar.dev/v1/packs/rabbitmq/0.1.14/03e0dc5ddbf0c1ee6515ce8f793fae9d39980eb130209fcc6576daa084308edf/pack.tar.gz","actions":[{"id":"rmq.close_connection","title":"rabbitmqctl close_connection","summary":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","description":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","kind":"exec","risk":"high","side_effects":["Connection is dropped with the given reason.","In-flight unacked messages on its channels go back to the queue."],"args":[{"name":"pid","type":"string","required":true,"description":"Connection PID (from list_connections).","validation":{"pattern":"^<[A-Za-z0-9@._-]{1,255}>$"}},{"name":"note","type":"string","required":false,"default":"Closed by operator","description":"Explanation recorded with the connection close.","validation":{"pattern":"^[A-Za-z0-9].{0,254}$"}}],"examples":[{"title":"Drop a stuck conn","args":{"pid":"<rabbit@host.1.123.0>"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["close_connection","{{ args.pid }}","{{ args.note }}"]}},{"id":"rmq.cluster_status","title":"rabbitmqctl cluster_status","summary":"Show cluster summary: nodes, alarms, partitions.","description":"Show cluster summary: nodes, alarms, partitions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Cluster status","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_bindings","title":"rabbitmqctl list_bindings","summary":"List all bindings between exchanges and queues.","description":"List all bindings between exchanges and queues.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Bindings","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_bindings"]}},{"id":"rmq.list_channels","title":"rabbitmqctl list_channels","summary":"List all open channels with consumer + prefetch + ack stats.","description":"List all open channels with consumer + prefetch + ack stats.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Channels","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_channels","pid","connection","consumer_count","messages_unacknowledged","prefetch_count"]}},{"id":"rmq.list_connections","title":"rabbitmqctl list_connections","summary":"List all open AMQP connections with client + user + channels.","description":"List all open AMQP connections with client + user + channels.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Connections","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_connections","pid","user","peer_host","peer_port","channels","state"]}},{"id":"rmq.list_consumers","title":"rabbitmqctl list_consumers","summary":"List all active consumers + their queue + ack-mode + prefetch.","description":"List all active consumers + their queue + ack-mode + prefetch.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Consumers","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_consumers"]}},{"id":"rmq.list_exchanges","title":"rabbitmqctl list_exchanges","summary":"List all exchanges with type + durability.","description":"List all exchanges with type + durability.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Exchanges","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_exchanges","name","type","durable"]}},{"id":"rmq.list_nodes","title":"Known cluster nodes","summary":"List all known cluster nodes.","description":"List all known cluster nodes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_parameters","title":"rabbitmqctl list_parameters","summary":"List runtime parameters (federation upstreams, shovel definitions, etc).","description":"List runtime parameters (federation upstreams, shovel definitions, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Parameters","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_parameters"]}},{"id":"rmq.list_policies","title":"rabbitmqctl list_policies","summary":"List all set policies (HA, federation, shovel, etc).","description":"List all set policies (HA, federation, shovel, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_policies"]}},{"id":"rmq.list_queues","title":"rabbitmqctl list_queues","summary":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","description":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Queue stats","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_queues","name","messages_ready","messages_unacknowledged","consumers","memory"]}},{"id":"rmq.list_users","title":"rabbitmqctl list_users","summary":"List all users + tags.","description":"List all users + tags.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Users","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_users"]}},{"id":"rmq.list_vhosts","title":"rabbitmqctl list_vhosts","summary":"List all virtual hosts.","description":"List all virtual hosts.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_vhosts"]}},{"id":"rmq.node_health_check","title":"rabbitmq-diagnostics check_running","summary":"Check health — confirms the local node is running and reachable.","description":"Check health — confirms the local node is running and reachable.","kind":"exec","risk":"low","side_effects":["One diagnostics call.","Read-only."],"args":[],"examples":[{"title":"Node health","args":{}}],"search_terms":[],"command":{"binary":"rabbitmq-diagnostics","argv":["check_running"]}},{"id":"rmq.purge_queue","title":"rabbitmqctl purge_queue","summary":"Drop every message in one queue. Unprocessed messages are lost.","description":"Drop every message in one queue. Unprocessed messages are lost.","kind":"exec","risk":"critical","side_effects":["All messages in the queue (including unacked-in-flight) are deleted."],"args":[{"name":"vhost","type":"string","required":true,"description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}},{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,254}$"}}],"examples":[{"title":"Purge dead-letter queue","args":{"queue":"dead-letters","vhost":"/"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["purge_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}},{"id":"rmq.start_app","title":"rabbitmqctl start_app","summary":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","description":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","kind":"exec","risk":"medium","side_effects":["RabbitMQ app accepts client connections again.","Queues and exchanges from disk become available."],"args":[],"examples":[{"title":"Start the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["start_app"]}},{"id":"rmq.stop_app","title":"rabbitmqctl stop_app","summary":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","description":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","kind":"exec","risk":"high","side_effects":["RabbitMQ app stops; clients disconnect.","Erlang node keeps running.","Producers fail; consumers reconnect when start_app runs."],"args":[],"examples":[{"title":"Stop the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["stop_app"]}},{"id":"rmq.sync_queue","title":"rabbitmqctl sync_queue","summary":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","description":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","kind":"exec","risk":"medium","side_effects":["Mirror catches up with the master.","I/O bandwidth used by sync.","Producers/consumers unaffected (small latency hit possible)."],"args":[{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_:./][a-zA-Z0-9_:.\\-/]{0,255}$"}},{"name":"vhost","type":"string","required":false,"default":"/","description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-/]{1,128}$"}}],"examples":[{"title":"Sync orders queue","args":{"queue":"orders"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["sync_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}}]},{"version":"0.1.12","content_hash":"sha256:abe12e6d29a7c1aad09364dcbcc899890d2d20f1912301637dc6a8cdd4ffdd1d","tarball_url":"https://registry.emisar.dev/v1/packs/rabbitmq/0.1.12/abe12e6d29a7c1aad09364dcbcc899890d2d20f1912301637dc6a8cdd4ffdd1d/pack.tar.gz","actions":[{"id":"rmq.close_connection","title":"rabbitmqctl close_connection","summary":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","description":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","kind":"exec","risk":"high","side_effects":["Connection is dropped with the given reason.","In-flight unacked messages on its channels go back to the queue."],"args":[{"name":"pid","type":"string","required":true,"description":"Connection PID (from list_connections).","validation":{"pattern":"^<[A-Za-z0-9@._-]{1,255}>$"}},{"name":"note","type":"string","required":false,"default":"Closed by operator","description":"Explanation recorded with the connection close.","validation":{"pattern":"^[A-Za-z0-9].{0,254}$"}}],"examples":[{"title":"Drop a stuck conn","args":{"pid":"<rabbit@host.1.123.0>"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["close_connection","{{ args.pid }}","{{ args.note }}"]}},{"id":"rmq.cluster_status","title":"rabbitmqctl cluster_status","summary":"Show cluster summary: nodes, alarms, partitions.","description":"Show cluster summary: nodes, alarms, partitions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Cluster status","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_bindings","title":"rabbitmqctl list_bindings","summary":"List all bindings between exchanges and queues.","description":"List all bindings between exchanges and queues.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Bindings","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_bindings"]}},{"id":"rmq.list_channels","title":"rabbitmqctl list_channels","summary":"List all open channels with consumer + prefetch + ack stats.","description":"List all open channels with consumer + prefetch + ack stats.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Channels","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_channels","pid","connection","consumer_count","messages_unacknowledged","prefetch_count"]}},{"id":"rmq.list_connections","title":"rabbitmqctl list_connections","summary":"List all open AMQP connections with client + user + channels.","description":"List all open AMQP connections with client + user + channels.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Connections","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_connections","pid","user","peer_host","peer_port","channels","state"]}},{"id":"rmq.list_consumers","title":"rabbitmqctl list_consumers","summary":"List all active consumers + their queue + ack-mode + prefetch.","description":"List all active consumers + their queue + ack-mode + prefetch.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Consumers","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_consumers"]}},{"id":"rmq.list_exchanges","title":"rabbitmqctl list_exchanges","summary":"List all exchanges with type + durability.","description":"List all exchanges with type + durability.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Exchanges","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_exchanges","name","type","durable"]}},{"id":"rmq.list_nodes","title":"Known cluster nodes","summary":"List all known cluster nodes.","description":"List all known cluster nodes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_parameters","title":"rabbitmqctl list_parameters","summary":"List runtime parameters (federation upstreams, shovel definitions, etc).","description":"List runtime parameters (federation upstreams, shovel definitions, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Parameters","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_parameters"]}},{"id":"rmq.list_policies","title":"rabbitmqctl list_policies","summary":"List all set policies (HA, federation, shovel, etc).","description":"List all set policies (HA, federation, shovel, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_policies"]}},{"id":"rmq.list_queues","title":"rabbitmqctl list_queues","summary":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","description":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Queue stats","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_queues","name","messages_ready","messages_unacknowledged","consumers","memory"]}},{"id":"rmq.list_users","title":"rabbitmqctl list_users","summary":"List all users + tags.","description":"List all users + tags.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Users","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_users"]}},{"id":"rmq.list_vhosts","title":"rabbitmqctl list_vhosts","summary":"List all virtual hosts.","description":"List all virtual hosts.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_vhosts"]}},{"id":"rmq.node_health_check","title":"rabbitmq-diagnostics check_running","summary":"Check health — confirms the local node is running and reachable.","description":"Check health — confirms the local node is running and reachable.","kind":"exec","risk":"low","side_effects":["One diagnostics call.","Read-only."],"args":[],"examples":[{"title":"Node health","args":{}}],"search_terms":[],"command":{"binary":"rabbitmq-diagnostics","argv":["check_running"]}},{"id":"rmq.purge_queue","title":"rabbitmqctl purge_queue","summary":"Drop every message in one queue. Unprocessed messages are lost.","description":"Drop every message in one queue. Unprocessed messages are lost.","kind":"exec","risk":"critical","side_effects":["All messages in the queue (including unacked-in-flight) are deleted."],"args":[{"name":"vhost","type":"string","required":true,"description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}},{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,254}$"}}],"examples":[{"title":"Purge dead-letter queue","args":{"queue":"dead-letters","vhost":"/"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["purge_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}},{"id":"rmq.start_app","title":"rabbitmqctl start_app","summary":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","description":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","kind":"exec","risk":"medium","side_effects":["RabbitMQ app accepts client connections again.","Queues and exchanges from disk become available."],"args":[],"examples":[{"title":"Start the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["start_app"]}},{"id":"rmq.stop_app","title":"rabbitmqctl stop_app","summary":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","description":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","kind":"exec","risk":"high","side_effects":["RabbitMQ app stops; clients disconnect.","Erlang node keeps running.","Producers fail; consumers reconnect when start_app runs."],"args":[],"examples":[{"title":"Stop the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["stop_app"]}},{"id":"rmq.sync_queue","title":"rabbitmqctl sync_queue","summary":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","description":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","kind":"exec","risk":"medium","side_effects":["Mirror catches up with the master.","I/O bandwidth used by sync.","Producers/consumers unaffected (small latency hit possible)."],"args":[{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_:./][a-zA-Z0-9_:.\\-/]{0,255}$"}},{"name":"vhost","type":"string","required":false,"default":"/","description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-/]{1,128}$"}}],"examples":[{"title":"Sync orders queue","args":{"queue":"orders"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["sync_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}}]},{"version":"0.1.11","content_hash":"sha256:ffa485fa22a9d1aaee74b3563e59081ec534560b473c6a97ca8a16da9a56ef9d","tarball_url":"https://registry.emisar.dev/v1/packs/rabbitmq/0.1.11/ffa485fa22a9d1aaee74b3563e59081ec534560b473c6a97ca8a16da9a56ef9d/pack.tar.gz","actions":[{"id":"rmq.close_connection","title":"rabbitmqctl close_connection","summary":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","description":"Forcibly closes one AMQP connection. Whatever client owned it must reconnect.","kind":"exec","risk":"high","side_effects":["Connection is dropped with the given reason.","In-flight unacked messages on its channels go back to the queue."],"args":[{"name":"pid","type":"string","required":true,"description":"Connection PID (from list_connections).","validation":{"pattern":"^<[A-Za-z0-9@._-]{1,255}>$"}},{"name":"note","type":"string","required":false,"default":"Closed by operator","description":"Explanation recorded with the connection close.","validation":{"pattern":"^[A-Za-z0-9].{0,254}$"}}],"examples":[{"title":"Drop a stuck conn","args":{"pid":"<rabbit@host.1.123.0>"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["close_connection","{{ args.pid }}","{{ args.note }}"]}},{"id":"rmq.cluster_status","title":"rabbitmqctl cluster_status","summary":"Show cluster summary: nodes, alarms, partitions.","description":"Show cluster summary: nodes, alarms, partitions.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Cluster status","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_bindings","title":"rabbitmqctl list_bindings","summary":"List all bindings between exchanges and queues.","description":"List all bindings between exchanges and queues.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Bindings","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_bindings"]}},{"id":"rmq.list_channels","title":"rabbitmqctl list_channels","summary":"List all open channels with consumer + prefetch + ack stats.","description":"List all open channels with consumer + prefetch + ack stats.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Channels","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_channels","pid","connection","consumer_count","messages_unacknowledged","prefetch_count"]}},{"id":"rmq.list_connections","title":"rabbitmqctl list_connections","summary":"List all open AMQP connections with client + user + channels.","description":"List all open AMQP connections with client + user + channels.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Connections","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_connections","pid","user","peer_host","peer_port","channels","state"]}},{"id":"rmq.list_consumers","title":"rabbitmqctl list_consumers","summary":"List all active consumers + their queue + ack-mode + prefetch.","description":"List all active consumers + their queue + ack-mode + prefetch.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Consumers","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_consumers"]}},{"id":"rmq.list_exchanges","title":"rabbitmqctl list_exchanges","summary":"List all exchanges with type + durability.","description":"List all exchanges with type + durability.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Exchanges","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_exchanges","name","type","durable"]}},{"id":"rmq.list_nodes","title":"Known cluster nodes","summary":"List all known cluster nodes.","description":"List all known cluster nodes.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Nodes","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["cluster_status"]}},{"id":"rmq.list_parameters","title":"rabbitmqctl list_parameters","summary":"List runtime parameters (federation upstreams, shovel definitions, etc).","description":"List runtime parameters (federation upstreams, shovel definitions, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Parameters","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_parameters"]}},{"id":"rmq.list_policies","title":"rabbitmqctl list_policies","summary":"List all set policies (HA, federation, shovel, etc).","description":"List all set policies (HA, federation, shovel, etc).","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_policies"]}},{"id":"rmq.list_queues","title":"rabbitmqctl list_queues","summary":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","description":"List all queues with name, messages_ready, messages_unacknowledged, consumers, memory. The canonical \"is anything backing up?\" check.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Queue stats","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_queues","name","messages_ready","messages_unacknowledged","consumers","memory"]}},{"id":"rmq.list_users","title":"rabbitmqctl list_users","summary":"List all users + tags.","description":"List all users + tags.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Users","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_users"]}},{"id":"rmq.list_vhosts","title":"rabbitmqctl list_vhosts","summary":"List all virtual hosts.","description":"List all virtual hosts.","kind":"exec","risk":"low","side_effects":["One CLI call.","Read-only."],"args":[],"examples":[{"title":"Vhosts","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["list_vhosts"]}},{"id":"rmq.node_health_check","title":"rabbitmq-diagnostics check_running","summary":"Check health — confirms the local node is running and reachable.","description":"Check health — confirms the local node is running and reachable.","kind":"exec","risk":"low","side_effects":["One diagnostics call.","Read-only."],"args":[],"examples":[{"title":"Node health","args":{}}],"search_terms":[],"command":{"binary":"rabbitmq-diagnostics","argv":["check_running"]}},{"id":"rmq.purge_queue","title":"rabbitmqctl purge_queue","summary":"Drop every message in one queue. Unprocessed messages are lost.","description":"Drop every message in one queue. Unprocessed messages are lost.","kind":"exec","risk":"critical","side_effects":["All messages in the queue (including unacked-in-flight) are deleted."],"args":[{"name":"vhost","type":"string","required":true,"description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_./\\-]{1,128}$"}},{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,254}$"}}],"examples":[{"title":"Purge dead-letter queue","args":{"queue":"dead-letters","vhost":"/"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["purge_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}},{"id":"rmq.start_app","title":"rabbitmqctl start_app","summary":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","description":"Start the RabbitMQ application within an already-running node. Companion to stop_app, used during cluster joins/leaves.","kind":"exec","risk":"medium","side_effects":["RabbitMQ app accepts client connections again.","Queues and exchanges from disk become available."],"args":[],"examples":[{"title":"Start the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["start_app"]}},{"id":"rmq.stop_app","title":"rabbitmqctl stop_app","summary":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","description":"Stop the RabbitMQ application while keeping the Erlang node running. Required before reset/join_cluster. All clients disconnect.","kind":"exec","risk":"high","side_effects":["RabbitMQ app stops; clients disconnect.","Erlang node keeps running.","Producers fail; consumers reconnect when start_app runs."],"args":[],"examples":[{"title":"Stop the app","args":{}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["stop_app"]}},{"id":"rmq.sync_queue","title":"rabbitmqctl sync_queue","summary":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","description":"Force a mirrored classic queue to sync with its master. Producers and consumers continue to operate; the sync runs in the background. Use when an unsynced mirror is blocking a master failover.","kind":"exec","risk":"medium","side_effects":["Mirror catches up with the master.","I/O bandwidth used by sync.","Producers/consumers unaffected (small latency hit possible)."],"args":[{"name":"queue","type":"string","required":true,"description":"Queue name.","validation":{"pattern":"^[a-zA-Z0-9_:./][a-zA-Z0-9_:.\\-/]{0,255}$"}},{"name":"vhost","type":"string","required":false,"default":"/","description":"Virtual host.","validation":{"pattern":"^[a-zA-Z0-9_:.\\-/]{1,128}$"}}],"examples":[{"title":"Sync orders queue","args":{"queue":"orders"}}],"search_terms":[],"command":{"binary":"rabbitmqctl","argv":["sync_queue","--vhost","{{ args.vhost }}","{{ args.queue }}"]}}]}],"retired_below":"0.1.9"},{"id":"redis","name":"Redis operations pack","version":"0.3.16","description":"Deep Redis ops — INFO + memory accounting, slowlog + per-event latency, command stats, client list/kill/pause, keyspace introspection (SCAN, TYPE, TTL, OBJECT encoding/refcount/idle/freq, MEMORY USAGE), config get/set/rewrite/resetstat, ACL list/whoami/getuser, cluster topology (info, nodes, slots, slot-count, check), cluster operators (failover, forget, replicaof), Sentinel HA topology (masters, master, replicas, sentinels, get-master-addr, ckquorum, is-master-down, Sentinel INFO) and operators (failover, reset), persistence (lastsave, bgsave, bgrewriteaof, memory purge/doctor), streams + pub/sub introspection, script cache flush, and tier-critical actions (flush_db, flushall, swapdb, shutdown_nosave). Sentinel actions target the Sentinel on port 26379; all others default to 127.0.0.1:6379. Authenticates via REDISCLI_AUTH / REDIS_* env vars on the runner host — never via per-call credentials.","vendor":"emisar","homepage":"https://emisar.dev/packs/redis","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/redis","content_hash":"sha256:bd5fc0cc0ed8b7b5bf89e9c42406a4dca86c8ae61e2e62d59e5bc8eff6ec7b85","tarball_url":"https://registry.emisar.dev/v1/packs/redis/0.3.16/bd5fc0cc0ed8b7b5bf89e9c42406a4dca86c8ae61e2e62d59e5bc8eff6ec7b85/pack.tar.gz","requires":{"os":["linux"],"binaries":["redis-cli"]},"detect":{"binaries":[],"processes":["redis-server"],"ports":[6379]},"setup":{"summary":"redis-cli authenticates with the password in `REDISCLI_AUTH` on the runner host. Ordinary Redis actions target the local instance at 127.0.0.1:6379; Sentinel actions pass only `-p 26379` and target the local Sentinel. No action reads a destination from the environment or accepts one as an argument.","env":[{"name":"REDISCLI_AUTH","description":"Password sent via AUTH. Omit for an instance with no requirepass/ACL. The matching user must hold the commands the actions you enable will run."}],"notes":["`REDISCLI_AUTH` must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Host and port are not configurable through this pack's env — ordinary actions use redis-cli's 127.0.0.1:6379 default, while Sentinel actions set only port 26379 and keep the same local host.","Sentinel must accept the same `REDISCLI_AUTH` password as the ordinary Redis service; every Sentinel action uses that shared runner credential on local port 26379.","`REDISCLI_AUTH` supplies only the password; for an ACL-enabled server with a non-default username, set requirepass-style access or run the runner as a user whose default ACL covers these commands.","Critical mutators (flush_db, flushall, swapdb, shutdown_nosave) and config writes need an ACL/user permitted to run them."],"verify":"redis.info"},"actions":[{"id":"redis.acl_getuser","title":"ACL GETUSER","summary":"Get the full rule listing for one ACL user — categories, commands, key patterns, channel patterns, flags. Read-only.","description":"Get the full rule listing for one ACL user — categories, commands, key patterns, channel patterns, flags. Read-only.","kind":"exec","risk":"medium","side_effects":["One ACL GETUSER command.","Read-only."],"args":[{"name":"username","type":"string","required":true,"description":"ACL username.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Inspect \"metrics\" user","args":{"username":"metrics"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ACL","GETUSER","{{ args.username }}"]}},{"id":"redis.acl_list","title":"ACL LIST","summary":"List all ACL users and their rules. Read-only. Use to audit access before changing a key namespace.","description":"List all ACL users and their rules. Read-only. Use to audit access before changing a key namespace.","kind":"exec","risk":"medium","side_effects":["One ACL LIST command.","Read-only."],"args":[],"examples":[{"title":"All ACL users","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ACL","LIST"]}},{"id":"redis.acl_whoami","title":"ACL WHOAMI","summary":"Show the ACL username of the current connection. Use to verify the runner credential is the expected service principal.","description":"Show the ACL username of the current connection. Use to verify the runner credential is the expected service principal.","kind":"exec","risk":"low","side_effects":["One ACL WHOAMI command.","Read-only."],"args":[],"examples":[{"title":"Connected user","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ACL","WHOAMI"]}},{"id":"redis.bgrewriteaof","title":"BGREWRITEAOF","summary":"Rewrite the AOF file in the background, compacting it to the smallest equivalent command set. Reduces AOF size and recovery time. Brief fork. Concurrent BGSAVE will queue.","description":"Rewrite the AOF file in the background, compacting it to the smallest equivalent command set. Reduces AOF size and recovery time. Brief fork. Concurrent BGSAVE will queue.","kind":"exec","risk":"medium","side_effects":["One fork; brief CPU + memory spike.","Writes a new AOF file then renames into place.","Concurrent BGSAVE will queue behind this."],"args":[],"examples":[{"title":"Compact AOF","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["BGREWRITEAOF"]}},{"id":"redis.bgsave","title":"BGSAVE","summary":"Trigger a background RDB snapshot. The fork briefly doubles RSS (copy-on-write). Returns immediately — completion shows in INFO rdb_last_bgsave_status. Concurrent BGREWRITEAOF will queue.","description":"Trigger a background RDB snapshot. The fork briefly doubles RSS (copy-on-write). Returns immediately — completion shows in INFO rdb_last_bgsave_status. Concurrent BGREWRITEAOF will queue.","kind":"exec","risk":"medium","side_effects":["One fork; brief CPU + memory spike.","Writes an RDB file to disk.","Concurrent BGREWRITEAOF will queue behind this."],"args":[],"examples":[{"title":"Trigger background snapshot","args":{}}],"search_terms":["backup now"],"command":{"binary":"redis-cli","argv":["BGSAVE"]}},{"id":"redis.client_kill","title":"CLIENT KILL","summary":"Disconnect one client by addr or by id. Use to evict a stuck client with a runaway output buffer, an abandoned subscriber, or a client exceeding the slowlog. Confirm the target via `client_list` first — killing the wrong client can disrupt a critical caller.","description":"Disconnect one client by addr or by id. Use to evict a stuck client with a runaway output buffer, an abandoned subscriber, or a client exceeding the slowlog. Confirm the target via `client_list` first — killing the wrong client can disrupt a critical caller.","kind":"exec","risk":"high","side_effects":["Forcibly closes the target connection.","In-flight commands on that connection are not replied to.","The client must reconnect."],"args":[{"name":"target","type":"string","required":true,"description":"ID like \"42\" or addr like \"10.0.0.5:53212\".","validation":{"pattern":"^[0-9a-fA-F.:]{1,64}$"}},{"name":"mode","type":"string","required":false,"default":"ADDR","description":"Whether `target` is an ADDR or an ID.","validation":{"enum":["ADDR","ID"]}}],"examples":[{"title":"Kill client by addr","args":{"mode":"ADDR","target":"10.0.0.5:53212"}},{"title":"Kill client by id","args":{"mode":"ID","target":"42"}}],"search_terms":["stuck client"],"command":{"binary":"redis-cli","argv":["CLIENT","KILL","{{ args.mode }}","{{ args.target }}"]}},{"id":"redis.client_list","title":"CLIENT LIST","summary":"Return every connected client with id, addr, name, age, idle, db, sub, psub, multi, qbuf, obl, oll, omem, cmd, fd. Use to find the client holding a long subscription, a runaway pipeline (large omem), or to identify candidate connections for CLIENT KILL.","description":"Return every connected client with id, addr, name, age, idle, db, sub, psub, multi, qbuf, obl, oll, omem, cmd, fd. Use to find the client holding a long subscription, a runaway pipeline (large omem), or to identify candidate connections for CLIENT KILL.","kind":"exec","risk":"low","side_effects":["Issues one CLIENT LIST command.","No keys read or written."],"args":[],"examples":[{"title":"List all connected clients","args":{}}],"search_terms":["too many connections","connection storm","who is connected"],"command":{"binary":"redis-cli","argv":["CLIENT","LIST"]}},{"id":"redis.client_pause","title":"CLIENT PAUSE","summary":"Pause all clients for N milliseconds. Used during safe failover windows to drain in-flight writes before flipping a master. Long pauses block all traffic — anything over 1s is a real outage. Replicas keep streaming during the pause.","description":"Pause all clients for N milliseconds. Used during safe failover windows to drain in-flight writes before flipping a master. Long pauses block all traffic — anything over 1s is a real outage. Replicas keep streaming during the pause.","kind":"exec","risk":"high","side_effects":["All clients stalled at the server side.","Pending requests buffer.","Memory may grow if clients keep sending."],"args":[{"name":"ms","type":"integer","required":true,"description":"Pause duration in milliseconds (1–10000).","validation":{"min":1,"max":10000}}],"examples":[{"title":"Pause 500ms during failover prep","args":{"ms":500}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLIENT","PAUSE","{{ args.ms }}"]}},{"id":"redis.cluster_check","title":"redis-cli --cluster check","summary":"Run `redis-cli --cluster check` from the local Redis entry point at 127.0.0.1:6379 — verifies slot coverage, master/replica health, and epoch consistency. Use after any topology change.","description":"Run `redis-cli --cluster check` from the local Redis entry point at 127.0.0.1:6379 — verifies slot coverage, master/replica health, and epoch consistency. Use after any topology change.","kind":"exec","risk":"low","side_effects":["Talks to every cluster node briefly.","Read-only."],"args":[],"examples":[{"title":"Local cluster check","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["--cluster","check","127.0.0.1:6379"]}},{"id":"redis.cluster_countkeysinslot","title":"CLUSTER COUNTKEYSINSLOT","summary":"Count keys mapped to a single hash slot. Use when a slot appears hot in monitoring to size the blast radius of a migration or to verify a tagged keyspace is collocated.","description":"Count keys mapped to a single hash slot. Use when a slot appears hot in monitoring to size the blast radius of a migration or to verify a tagged keyspace is collocated.","kind":"exec","risk":"low","side_effects":["One CLUSTER COUNTKEYSINSLOT command.","Read-only."],"args":[{"name":"slot","type":"integer","required":true,"description":"Hash slot (0–16383).","validation":{"min":0,"max":16383}}],"examples":[{"title":"Key count in slot 5000","args":{"slot":5000}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","COUNTKEYSINSLOT","{{ args.slot }}"]}},{"id":"redis.cluster_failover","title":"CLUSTER FAILOVER","summary":"Promote the connected REPLICA to master. Default mode (empty) waits for replication parity — the only safe choice during a planned failover. FORCE skips parity (use only when master is suspected dead). TAKEOVER bypasses cluster consensus entirely (split-brain recovery). Run while connected to a REPLICA, not a master.","description":"Promote the connected REPLICA to master. Default mode (empty) waits for replication parity — the only safe choice during a planned failover. FORCE skips parity (use only when master is suspected dead). TAKEOVER bypasses cluster consensus entirely (split-brain recovery). Run while connected to a REPLICA, not a master.","kind":"exec","risk":"critical","side_effects":["The connected replica becomes master.","The previous master becomes a replica.","Brief slot-ownership flip; some commands may transiently fail.","Other replicas reconfigure to follow the new master."],"args":[{"name":"mode","type":"string","required":false,"default":"","description":"Empty (safe), FORCE, or TAKEOVER.","validation":{"enum":["","FORCE","TAKEOVER"]}}],"examples":[{"title":"Safe failover from replica","args":{}},{"title":"Force failover (master suspected dead)","args":{"mode":"FORCE"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","redis-cli CLUSTER FAILOVER {{ args.mode }}"]}},{"id":"redis.cluster_forget","title":"CLUSTER FORGET","summary":"Remove a node from the connected node's cluster view for 60s. Used during node replacement. Run on every reachable node to fully evict the old member. Wrong target id produces a brief split view until gossip refreshes.","description":"Remove a node from the connected node's cluster view for 60s. Used during node replacement. Run on every reachable node to fully evict the old member. Wrong target id produces a brief split view until gossip refreshes.","kind":"exec","risk":"high","side_effects":["The connected node drops the named member from its view.","Effect lasts 60 seconds; gossip may re-discover an alive node.","Run on every node to permanently evict."],"args":[{"name":"node_id","type":"string","required":true,"description":"40-char hex node id.","validation":{"pattern":"^[a-f0-9]{40}$"}}],"examples":[{"title":"Forget a node","args":{"node_id":"07c37dfeb235213a872192d90877d0cd55635b91"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","FORGET","{{ args.node_id }}"]}},{"id":"redis.cluster_info","title":"CLUSTER INFO","summary":"Show cluster status — state ok/fail, slots assigned/ok/pfail/fail, known nodes, size, epoch, my epoch, messages sent/received.","description":"Show cluster status — state ok/fail, slots assigned/ok/pfail/fail, known nodes, size, epoch, my epoch, messages sent/received.","kind":"exec","risk":"low","side_effects":["One CLUSTER INFO command.","Read-only."],"args":[],"examples":[{"title":"Cluster health summary","args":{}}],"search_terms":["cluster down","clusterdown"],"command":{"binary":"redis-cli","argv":["CLUSTER","INFO"]}},{"id":"redis.cluster_nodes","title":"CLUSTER NODES","summary":"List the cluster nodes — id, addr, flags (master/replica/myself/fail), master id, last ping/pong, config epoch, link state, slot ranges. Use to see who owns which slot ranges and which replicas serve which masters.","description":"List the cluster nodes — id, addr, flags (master/replica/myself/fail), master id, last ping/pong, config epoch, link state, slot ranges. Use to see who owns which slot ranges and which replicas serve which masters.","kind":"exec","risk":"low","side_effects":["One CLUSTER NODES command.","Read-only."],"args":[],"examples":[{"title":"Topology view","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","NODES"]}},{"id":"redis.cluster_slots","title":"CLUSTER SLOTS","summary":"Show the slot-range → master/replica mapping. Use to confirm a given hash slot is owned by the expected shard and to see replica addresses for read traffic.","description":"Show the slot-range → master/replica mapping. Use to confirm a given hash slot is owned by the expected shard and to see replica addresses for read traffic.","kind":"exec","risk":"low","side_effects":["One CLUSTER SLOTS command.","Read-only."],"args":[],"examples":[{"title":"Slot ownership map","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","SLOTS"]}},{"id":"redis.command_stats","title":"INFO commandstats","summary":"Return per-command call count, total µs spent, and µs per call. Use to identify hot commands (e.g. an unexpectedly high KEYS rate or a SUBSCRIBE storm). Read-only.","description":"Return per-command call count, total µs spent, and µs per call. Use to identify hot commands (e.g. an unexpectedly high KEYS rate or a SUBSCRIBE storm). Read-only.","kind":"exec","risk":"low","side_effects":["Issues one INFO commandstats command.","No keys read or written."],"args":[],"examples":[{"title":"Per-command stats","args":{}}],"search_terms":["hot commands"],"command":{"binary":"redis-cli","argv":["INFO","commandstats"]}},{"id":"redis.config_get","title":"CONFIG GET","summary":"Read runtime config by glob pattern. Useful before any tuning conversation: confirm `maxmemory`, `maxmemory-policy`, `appendonly`, `save`, etc. Read-only. Pattern is restricted to safe globs against Redis config keys. Credential values are masked in the output — the key stays visible so you can see it is set.","description":"Read runtime config by glob pattern. Useful before any tuning conversation: confirm `maxmemory`, `maxmemory-policy`, `appendonly`, `save`, etc. Read-only. Pattern is restricted to safe globs against Redis config keys. Credential values are masked in the output — the key stays visible so you can see it is set.","kind":"exec","risk":"medium","side_effects":["Issues one CONFIG GET command.","No keys read or written.","Read-only, but the default `*` pattern returns the whole server config.","Redis owns this key space, so its credential keys are enumerable rather than guessed at. On 7.4.10 they are requirepass, masterauth, tls-key-file-pass and tls-client-key-file-pass.","Every one of those ends in a suffix the redaction rule matches. The near misses (masteruser, tls-key-file, tls-auth-clients) are a username, a path and a mode, not secrets.","That established coverage is why this is medium. A config that operators author as free text, like an nginx or Caddy dump, cannot claim it and stays high."],"args":[{"name":"pattern","type":"string","required":false,"default":"*","description":"Glob pattern (e.g. \"maxmemory*\", \"save\", \"*\").","validation":{"pattern":"^[a-zA-Z0-9_*?][a-zA-Z0-9_\\-*?]{0,63}$"}}],"examples":[{"title":"Memory-related config","args":{"pattern":"maxmemory*"}},{"title":"All persistence settings","args":{"pattern":"save"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CONFIG","GET","{{ args.pattern }}"]}},{"id":"redis.config_resetstat","title":"CONFIG RESETSTAT","summary":"Reset INFO stats counters (commandstats, keyspace hits/misses, evictions, etc.). Does NOT change keyspace data, but it DOES mutate server state by zeroing the counters — so it is risk:medium (policy-gated), like the other non-keyspace mutators (memory_purge, script_flush). Use to start a fresh measurement window.","description":"Reset INFO stats counters (commandstats, keyspace hits/misses, evictions, etc.). Does NOT change keyspace data, but it DOES mutate server state by zeroing the counters — so it is risk:medium (policy-gated), like the other non-keyspace mutators (memory_purge, script_flush). Use to start a fresh measurement window.","kind":"exec","risk":"medium","side_effects":["INFO counters zero.","No keys read or written."],"args":[],"examples":[{"title":"Reset stats","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CONFIG","RESETSTAT"]}},{"id":"redis.config_rewrite","title":"CONFIG REWRITE","summary":"Persist all runtime CONFIG SET changes back to the on-disk redis.conf. Without this, runtime overrides revert at restart.","description":"Persist all runtime CONFIG SET changes back to the on-disk redis.conf. Without this, runtime overrides revert at restart.","kind":"exec","risk":"medium","side_effects":["Rewrites redis.conf in place (preserves comments, updates values).","No keyspace changes."],"args":[],"examples":[{"title":"Persist runtime config","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CONFIG","REWRITE"]}},{"id":"redis.config_set","title":"CONFIG SET","summary":"Change one runtime config parameter. Effects are immediate and may include eviction policy, persistence mode, replication behavior. Combine with config_rewrite to persist. Value pattern is restricted to safe characters.","description":"Change one runtime config parameter. Effects are immediate and may include eviction policy, persistence mode, replication behavior. Combine with config_rewrite to persist. Value pattern is restricted to safe characters.","kind":"exec","risk":"high","side_effects":["Runtime behavior changes immediately.","Some parameters affect persistence, replication, eviction.","Not persisted across restart without CONFIG REWRITE."],"args":[{"name":"parameter","type":"string","required":true,"description":"Config parameter name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"value","type":"string","required":true,"description":"New value (limited charset).","validation":{"pattern":"^[a-zA-Z0-9_./ %:][a-zA-Z0-9_\\-./ %:]{0,255}$"}}],"examples":[{"title":"Raise maxmemory","args":{"parameter":"maxmemory","value":"4gb"}}],"search_terms":["set maxmemory","change eviction policy"],"command":{"binary":"redis-cli","argv":["CONFIG","SET","{{ args.parameter }}","{{ args.value }}"]}},{"id":"redis.dbsize","title":"DBSIZE","summary":"Return the number of keys in the currently selected database. O(1). Read-only. Use as a sanity check before running operations that scan the keyspace.","description":"Return the number of keys in the currently selected database. O(1). Read-only. Use as a sanity check before running operations that scan the keyspace.","kind":"exec","risk":"low","side_effects":["Issues one DBSIZE command.","No keys read or written."],"args":[{"name":"db","type":"integer","required":false,"default":0,"description":"Logical database index.","validation":{"min":0,"max":15}}],"examples":[{"title":"Key count in DB 0","args":{}}],"search_terms":["key count","how many keys"],"command":{"binary":"redis-cli","argv":["-n","{{ args.db }}","DBSIZE"]}},{"id":"redis.flush_db","title":"FLUSHDB (single database)","summary":"Delete every key in one logical database. Irreversible. Use only on caches and only when you know there is no replication consumer that treats an empty DB as a fault. ASYNC mode returns immediately and drops the data in a background thread; SYNC blocks until done. Never use against production user data — this exists for cache resets and dev environments.","description":"Delete every key in one logical database. Irreversible. Use only on caches and only when you know there is no replication consumer that treats an empty DB as a fault. ASYNC mode returns immediately and drops the data in a background thread; SYNC blocks until done. Never use against production user data — this exists for cache resets and dev environments.","kind":"exec","risk":"critical","side_effects":["All keys in the selected database are deleted.","Replicas FLUSHDB in turn.","No way to recover except by restore."],"args":[{"name":"db","type":"integer","required":true,"description":"Database index to flush.","validation":{"min":0,"max":15}},{"name":"mode","type":"string","required":false,"default":"ASYNC","description":"Run synchronously or async.","validation":{"enum":["SYNC","ASYNC"]}}],"examples":[{"title":"Async flush of cache DB 2","args":{"db":2,"mode":"ASYNC"}}],"search_terms":["clear cache","empty cache"],"command":{"binary":"redis-cli","argv":["-n","{{ args.db }}","FLUSHDB","{{ args.mode }}"]}},{"id":"redis.flushall","title":"FLUSHALL","summary":"Delete EVERY key from EVERY database. Irreversible. Replicas FLUSHALL in turn. Only use on caches that can be cold-rebuilt.","description":"Delete EVERY key from EVERY database. Irreversible. Replicas FLUSHALL in turn. Only use on caches that can be cold-rebuilt.","kind":"exec","risk":"critical","side_effects":["All databases emptied.","Replicas wipe in turn.","No recovery except restore."],"args":[{"name":"mode","type":"string","required":false,"default":"ASYNC","description":"SYNC (block) or ASYNC (return, drop in background).","validation":{"enum":["SYNC","ASYNC"]}}],"examples":[{"title":"Async wipe all DBs","args":{}}],"search_terms":["clear all caches"],"command":{"binary":"redis-cli","argv":["FLUSHALL","{{ args.mode }}"]}},{"id":"redis.info","title":"Redis INFO section","summary":"Run `INFO <section>` and return the raw text. Sections: server, clients, memory, persistence, stats, replication, cpu, commandstats, latencystats, cluster, keyspace, errorstats, all. Read-only.","description":"Run `INFO <section>` and return the raw text. Sections: server, clients, memory, persistence, stats, replication, cpu, commandstats, latencystats, cluster, keyspace, errorstats, all. Read-only.","kind":"exec","risk":"low","side_effects":["Issues one INFO command.","No keys read or written."],"args":[{"name":"section","type":"string","required":false,"default":"default","description":"INFO section.","validation":{"enum":["default","all","server","clients","memory","persistence","stats","replication","cpu","commandstats","latencystats","cluster","keyspace","errorstats"]}}],"examples":[{"title":"Default INFO","args":{}},{"title":"Memory-only INFO","args":{"section":"memory"}}],"search_terms":["cache health","cache unhealthy","hit rate","evictions"],"command":{"binary":"redis-cli","argv":["INFO","{{ args.section }}"]}},{"id":"redis.lastsave","title":"LASTSAVE","summary":"Show the Unix timestamp of the last successful background save (RDB). Use to confirm the persistence schedule is firing.","description":"Show the Unix timestamp of the last successful background save (RDB). Use to confirm the persistence schedule is firing.","kind":"exec","risk":"low","side_effects":["One LASTSAVE command.","Read-only."],"args":[],"examples":[{"title":"Last RDB timestamp","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["LASTSAVE"]}},{"id":"redis.latency","title":"LATENCY LATEST + HISTORY","summary":"Run `LATENCY LATEST` to summarize per-event latency spikes (fork, AOF write, expire, eviction, command, etc.). Requires `latency-monitor-threshold` to be set non-zero in redis.conf; if it isn't, the output is empty and that is a configuration finding worth reporting. Read-only.","description":"Run `LATENCY LATEST` to summarize per-event latency spikes (fork, AOF write, expire, eviction, command, etc.). Requires `latency-monitor-threshold` to be set non-zero in redis.conf; if it isn't, the output is empty and that is a configuration finding worth reporting. Read-only.","kind":"exec","risk":"low","side_effects":["Issues one LATENCY LATEST command.","No keys read or written."],"args":[],"examples":[{"title":"Show latest latency events","args":{}}],"search_terms":["intermittent stalls"],"command":{"binary":"redis-cli","argv":["LATENCY","LATEST"]}},{"id":"redis.latency_history","title":"LATENCY HISTORY","summary":"Show per-event latency time series (e.g. fork, aof-write, expire). Use after LATENCY LATEST to drill into one event class.","description":"Show per-event latency time series (e.g. fork, aof-write, expire). Use after LATENCY LATEST to drill into one event class.","kind":"exec","risk":"low","side_effects":["One LATENCY HISTORY command.","Read-only."],"args":[{"name":"event","type":"string","required":true,"description":"Event name from LATENCY LATEST.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-_]{0,31}$"}}],"examples":[{"title":"Fork latency history","args":{"event":"fork"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["LATENCY","HISTORY","{{ args.event }}"]}},{"id":"redis.memory_doctor","title":"MEMORY DOCTOR","summary":"Run the built-in memory advisor. Returns a human-readable summary of suspected issues (fragmentation, oversized clients, large peak vs current).","description":"Run the built-in memory advisor. Returns a human-readable summary of suspected issues (fragmentation, oversized clients, large peak vs current).","kind":"exec","risk":"low","side_effects":["One MEMORY DOCTOR command.","Read-only."],"args":[],"examples":[{"title":"Memory advisor","args":{}}],"search_terms":["cache health","cache unhealthy","memory fragmentation"],"command":{"binary":"redis-cli","argv":["MEMORY","DOCTOR"]}},{"id":"redis.memory_purge","title":"MEMORY PURGE","summary":"Ask jemalloc to release unused memory back to the OS. Use after a large eviction or DEL spike when RSS hasn't dropped despite used_memory falling. Brief allocator pause possible.","description":"Ask jemalloc to release unused memory back to the OS. Use after a large eviction or DEL spike when RSS hasn't dropped despite used_memory falling. Brief allocator pause possible.","kind":"exec","risk":"medium","side_effects":["Brief allocator pause.","RSS may drop afterwards.","Does not affect keys."],"args":[],"examples":[{"title":"Release jemalloc-cached memory","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["MEMORY","PURGE"]}},{"id":"redis.memory_stats","title":"MEMORY STATS","summary":"Run `MEMORY STATS`. Returns the detailed memory accounting (allocator stats, fragmentation, peak, overheads, replication backlog, client and AOF buffers). Read-only. Use to diagnose OOM warnings before resizing.","description":"Run `MEMORY STATS`. Returns the detailed memory accounting (allocator stats, fragmentation, peak, overheads, replication backlog, client and AOF buffers). Read-only. Use to diagnose OOM warnings before resizing.","kind":"exec","risk":"low","side_effects":["Issues one MEMORY STATS command.","No keys read or written."],"args":[],"examples":[{"title":"Detailed memory accounting","args":{}}],"search_terms":["memory breakdown","oom warnings"],"command":{"binary":"redis-cli","argv":["MEMORY","STATS"]}},{"id":"redis.memory_usage","title":"MEMORY USAGE key","summary":"Show bytes used by a single key (estimate, including value and internal overhead). Use to find a known big-value culprit before a deletion conversation.","description":"Show bytes used by a single key (estimate, including value and internal overhead). Use to find a known big-value culprit before a deletion conversation.","kind":"exec","risk":"low","side_effects":["One MEMORY USAGE command.","Reads metadata but not the value."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Size of a session key","args":{"key":"session:abc123"}}],"search_terms":["big key","key size"],"command":{"binary":"redis-cli","argv":["MEMORY","USAGE","{{ args.key }}"]}},{"id":"redis.object_encoding","title":"OBJECT ENCODING key","summary":"Show the internal encoding of one value (ziplist, hashtable, intset, listpack, quicklist, embstr, raw, skiplist). Use to confirm a structure is in its compact form before tuning size limits.","description":"Show the internal encoding of one value (ziplist, hashtable, intset, listpack, quicklist, embstr, raw, skiplist). Use to confirm a structure is in its compact form before tuning size limits.","kind":"exec","risk":"low","side_effects":["One OBJECT ENCODING command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Encoding of a hash","args":{"key":"user:42"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","ENCODING","{{ args.key }}"]}},{"id":"redis.object_freq","title":"OBJECT FREQ key","summary":"Show the LFU access-frequency counter for the key. Requires an LFU maxmemory-policy. Use to compare access patterns across a candidate eviction set.","description":"Show the LFU access-frequency counter for the key. Requires an LFU maxmemory-policy. Use to compare access patterns across a candidate eviction set.","kind":"exec","risk":"low","side_effects":["One OBJECT FREQ command.","Read-only metadata; does not bump the frequency counter."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Access frequency","args":{"key":"user:42"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","FREQ","{{ args.key }}"]}},{"id":"redis.object_idletime","title":"OBJECT IDLETIME key","summary":"Show seconds since the key was last accessed. Requires an LRU maxmemory-policy. Use to identify cold keys for manual eviction.","description":"Show seconds since the key was last accessed. Requires an LRU maxmemory-policy. Use to identify cold keys for manual eviction.","kind":"exec","risk":"low","side_effects":["One OBJECT IDLETIME command.","Read-only metadata; does not bump LRU age."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"How cold is this key?","args":{"key":"user:42"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","IDLETIME","{{ args.key }}"]}},{"id":"redis.object_refcount","title":"OBJECT REFCOUNT key","summary":"Show the reference count for a value. Shared integers report INT_MAX; every other value reports 1. Use to confirm the shared-integer optimization is hitting (or not).","description":"Show the reference count for a value. Shared integers report INT_MAX; every other value reports 1. Use to confirm the shared-integer optimization is hitting (or not).","kind":"exec","risk":"low","side_effects":["One OBJECT REFCOUNT command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Refcount of a counter","args":{"key":"stats:requests"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","REFCOUNT","{{ args.key }}"]}},{"id":"redis.pubsub_channels","title":"PUBSUB CHANNELS","summary":"List active pub/sub channels matching the optional pattern. Useful to see which event streams a service is producing.","description":"List active pub/sub channels matching the optional pattern. Useful to see which event streams a service is producing.","kind":"exec","risk":"low","side_effects":["One PUBSUB CHANNELS command.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"*","description":"Glob pattern.","validation":{"pattern":"^[A-Za-z0-9_:.*?{}@#/=+][A-Za-z0-9_:.\\-*?{}@#/=+]{0,255}$"}}],"examples":[{"title":"All active channels","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["PUBSUB","CHANNELS","{{ args.pattern }}"]}},{"id":"redis.pubsub_numsub","title":"PUBSUB NUMSUB","summary":"Count subscribers on a channel. Useful before tearing down a producer.","description":"Count subscribers on a channel. Useful before tearing down a producer.","kind":"exec","risk":"low","side_effects":["One PUBSUB NUMSUB command.","Read-only."],"args":[{"name":"channel","type":"string","required":true,"description":"Channel name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,255}$"}}],"examples":[{"title":"Subscribers on events.user","args":{"channel":"events.user"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["PUBSUB","NUMSUB","{{ args.channel }}"]}},{"id":"redis.randomkey","title":"RANDOMKEY","summary":"Return a random key from the current database (or nil if empty). Useful for sampling key shapes.","description":"Return a random key from the current database (or nil if empty). Useful for sampling key shapes.","kind":"exec","risk":"low","side_effects":["One RANDOMKEY command.","Read-only."],"args":[],"examples":[{"title":"Sample one key","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["RANDOMKEY"]}},{"id":"redis.replicaof","title":"REPLICAOF","summary":"Reconfigure replication. REPLICAOF NO ONE promotes this node to master (used in unmanaged failover). REPLICAOF host port reassigns this node as a replica of host:port and triggers a full sync — the local dataset is REPLACED. Misuse can wipe live data.","description":"Reconfigure replication. REPLICAOF NO ONE promotes this node to master (used in unmanaged failover). REPLICAOF host port reassigns this node as a replica of host:port and triggers a full sync — the local dataset is REPLACED. Misuse can wipe live data.","kind":"exec","risk":"critical","side_effects":["Replication topology changes immediately.","If becoming a replica: local dataset is replaced by the new master's snapshot.","If promoted to master: existing replicas of the old master may still follow it."],"args":[{"name":"host","type":"string","required":true,"description":"New master host, or the literal \"NO\" to demote.","validation":{"pattern":"^[a-zA-Z0-9._][a-zA-Z0-9._\\-]{0,252}$"}},{"name":"port","type":"string","required":true,"description":"New master port (1-65535), or the literal \"ONE\" if host is \"NO\".","validation":{"pattern":"^([1-9][0-9]{0,4}|ONE)$"}}],"examples":[{"title":"Promote to master","args":{"host":"NO","port":"ONE"}},{"title":"Become replica of 10.0.0.5:6379","args":{"host":"10.0.0.5","port":"6379"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["REPLICAOF","{{ args.host }}","{{ args.port }}"]}},{"id":"redis.role","title":"ROLE","summary":"Report whether this Redis is master, replica, or sentinel. Master shows replication offset and connected replicas; replica shows master addr + sync state. Use before any write-path troubleshooting.","description":"Report whether this Redis is master, replica, or sentinel. Master shows replication offset and connected replicas; replica shows master addr + sync state. Use before any write-path troubleshooting.","kind":"exec","risk":"low","side_effects":["One ROLE command.","Read-only."],"args":[],"examples":[{"title":"Replication role","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ROLE"]}},{"id":"redis.scan","title":"SCAN cursor MATCH COUNT","summary":"Show one SCAN page. Returns next-cursor + up to COUNT keys matching MATCH. Safe for prod — never blocks. Use to enumerate a hot namespace without KEYS.","description":"Show one SCAN page. Returns next-cursor + up to COUNT keys matching MATCH. Safe for prod — never blocks. Use to enumerate a hot namespace without KEYS.","kind":"exec","risk":"low","side_effects":["One SCAN command.","Read-only metadata; values are not fetched."],"args":[{"name":"cursor","type":"string","required":false,"default":"0","description":"Cursor (start with \"0\").","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"match","type":"string","required":false,"default":"*","description":"Glob pattern.","validation":{"pattern":"^[A-Za-z0-9_:.*?{}@#/=+][A-Za-z0-9_:.\\-*?{}@#/=+]{0,255}$"}},{"name":"count","type":"integer","required":false,"default":100,"description":"Server hint for batch size.","validation":{"min":1,"max":10000}}],"examples":[{"title":"First page of session keys","args":{"count":200,"match":"session:*"}}],"search_terms":["list keys","find keys by pattern"],"command":{"binary":"redis-cli","argv":["SCAN","{{ args.cursor }}","MATCH","{{ args.match }}","COUNT","{{ args.count }}"]}},{"id":"redis.script_flush","title":"SCRIPT FLUSH","summary":"Drop all cached EVAL scripts (server-side Lua). Clients using EVAL repopulate naturally; clients using EVALSHA hit NOSCRIPT until they re-cache.","description":"Drop all cached EVAL scripts (server-side Lua). Clients using EVAL repopulate naturally; clients using EVALSHA hit NOSCRIPT until they re-cache.","kind":"exec","risk":"medium","side_effects":["Script cache cleared.","Brief NOSCRIPT errors expected on EVALSHA callers."],"args":[{"name":"mode","type":"string","required":false,"default":"ASYNC","description":"SYNC (block) or ASYNC (return immediately).","validation":{"enum":["SYNC","ASYNC"]}}],"examples":[{"title":"Async script flush","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["SCRIPT","FLUSH","{{ args.mode }}"]}},{"id":"redis.sentinel_ckquorum","title":"SENTINEL CKQUORUM","summary":"Check whether enough Sentinels are reachable to BOTH reach the failover quorum AND form the majority needed to authorize a failover for the named master. The canonical pre-failover health check — returns OK with the counts, or an error if a failover could not currently proceed. Connects to the Sentinel on port 26379. Read-only.","description":"Check whether enough Sentinels are reachable to BOTH reach the failover quorum AND form the majority needed to authorize a failover for the named master. The canonical pre-failover health check — returns OK with the counts, or an error if a failover could not currently proceed. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL CKQUORUM command on the local Sentinel (port 26379).","No Sentinel state changed, no failover triggered."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name to check quorum for (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Can mymaster be failed over right now?","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","CKQUORUM","{{ args.master_name }}"]}},{"id":"redis.sentinel_failover","title":"SENTINEL FAILOVER","summary":"Force a failover for the named master as if it were unreachable, WITHOUT asking the other Sentinels for agreement (a new configuration is still published so the peers update). Promotes a replica to master and reconfigures the rest to follow it. This is a manual, operator-initiated failover — use for a planned switchover or to recover when automatic failover is stuck. Connects to the Sentinel on port 26379.","description":"Force a failover for the named master as if it were unreachable, WITHOUT asking the other Sentinels for agreement (a new configuration is still published so the peers update). Promotes a replica to master and reconfigures the rest to follow it. This is a manual, operator-initiated failover — use for a planned switchover or to recover when automatic failover is stuck. Connects to the Sentinel on port 26379.","kind":"exec","risk":"high","side_effects":["The named master is failed over; a replica is promoted to master.","Remaining replicas are reconfigured to replicate from the new master.","The new topology is published to all Sentinels; clients are redirected.","Brief write unavailability during the promotion."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name to fail over (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Force failover of mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","FAILOVER","{{ args.master_name }}"]}},{"id":"redis.sentinel_get_master_addr","title":"SENTINEL GET-MASTER-ADDR-BY-NAME","summary":"Return the ip and port Sentinel currently believes is the master for the named set. During or just after a failover this returns the PROMOTED replica's address — so it is the authoritative answer to \"who is the master right now?\" Compare against ROLE on each node to detect split-brain. Connects to the Sentinel on port 26379. Read-only.","description":"Return the ip and port Sentinel currently believes is the master for the named set. During or just after a failover this returns the PROMOTED replica's address — so it is the authoritative answer to \"who is the master right now?\" Compare against ROLE on each node to detect split-brain. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL GET-MASTER-ADDR-BY-NAME command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name to resolve (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Current master address for mymaster","args":{"master_name":"mymaster"}}],"search_terms":["who is the master","current master"],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","GET-MASTER-ADDR-BY-NAME","{{ args.master_name }}"]}},{"id":"redis.sentinel_info","title":"Sentinel INFO","summary":"Run INFO against the Sentinel process itself (port 26379) and return the raw text, including the `sentinel` section: sentinel_masters, sentinel_running_scripts, sentinel_tilt, and a master0..N line per monitored master (name, status, address, slaves, sentinels). Use to read the Sentinel's own health — e.g. whether it is in TILT mode. Read-only.","description":"Run INFO against the Sentinel process itself (port 26379) and return the raw text, including the `sentinel` section: sentinel_masters, sentinel_running_scripts, sentinel_tilt, and a master0..N line per monitored master (name, status, address, slaves, sentinels). Use to read the Sentinel's own health — e.g. whether it is in TILT mode. Read-only.","kind":"exec","risk":"low","side_effects":["One INFO command on the local Sentinel (port 26379).","No keys read or written; no Sentinel state changed."],"args":[{"name":"section","type":"string","required":false,"default":"default","description":"INFO section.","validation":{"enum":["default","all","server","clients","cpu","stats","sentinel"]}}],"examples":[{"title":"Sentinel INFO (default)","args":{}},{"title":"Sentinel section only","args":{"section":"sentinel"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","INFO","{{ args.section }}"]}},{"id":"redis.sentinel_is_master_down","title":"SENTINEL IS-MASTER-DOWN-BY-ADDR","summary":"Ask this Sentinel whether the master at ip:port is subjectively down from its point of view. Primarily an internal failover-consensus command, but useful read-only forensics when investigating WHY an objective-down (ODOWN) or failover did or did not fire. Always sends epoch 0 and run id \"*\", Redis's non-voting form. Connects to the Sentinel on port 26379. Read-only.","description":"Ask this Sentinel whether the master at ip:port is subjectively down from its point of view. Primarily an internal failover-consensus command, but useful read-only forensics when investigating WHY an objective-down (ODOWN) or failover did or did not fire. Always sends epoch 0 and run id \"*\", Redis's non-voting form. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL IS-MASTER-DOWN-BY-ADDR command on the local Sentinel (port 26379).","Fixed to epoch 0 and run id \"*\", so it cannot advance the election epoch or request a leader vote."],"args":[{"name":"ip","type":"string","required":true,"description":"Master IPv4/IPv6 address as Sentinel knows it.","validation":{"pattern":"^[0-9a-fA-F.:]{2,45}$"}},{"name":"port","type":"string","required":true,"description":"Master port (1-65535).","validation":{"pattern":"^[1-9][0-9]{0,4}$"}}],"examples":[{"title":"Is the master at 10.0.0.5:6379 down from this Sentinel's view?","args":{"ip":"10.0.0.5","port":"6379"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","IS-MASTER-DOWN-BY-ADDR","{{ args.ip }}","{{ args.port }}","0","*"]}},{"id":"redis.sentinel_master","title":"SENTINEL MASTER","summary":"Show the full state of one monitored master by its configured name (e.g. \"mymaster\") — ip:port, flags, quorum, num-slaves, num-other-sentinels, down-after-milliseconds, last-ping. Use to confirm a specific master's view and whether the configured quorum is met. Connects to the Sentinel on port 26379. Read-only.","description":"Show the full state of one monitored master by its configured name (e.g. \"mymaster\") — ip:port, flags, quorum, num-slaves, num-other-sentinels, down-after-milliseconds, last-ping. Use to confirm a specific master's view and whether the configured quorum is met. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL MASTER command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name Sentinel monitors (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"State of master mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","MASTER","{{ args.master_name }}"]}},{"id":"redis.sentinel_masters","title":"SENTINEL MASTERS","summary":"List every master this Sentinel monitors with full state — name, ip:port, quorum, flags (master/o_down/s_down), num-slaves, num-other-sentinels. Connects to the Sentinel on port 26379. The first stop when mapping a replicas+Sentinel topology. Read-only.","description":"List every master this Sentinel monitors with full state — name, ip:port, quorum, flags (master/o_down/s_down), num-slaves, num-other-sentinels. Connects to the Sentinel on port 26379. The first stop when mapping a replicas+Sentinel topology. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL MASTERS command on the local Sentinel (port 26379).","No Sentinel state changed, no failover triggered."],"args":[],"examples":[{"title":"All monitored masters","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","MASTERS"]}},{"id":"redis.sentinel_replicas","title":"SENTINEL REPLICAS","summary":"List the replicas Sentinel has discovered for one master, each with ip:port, flags (slave/s_down/disconnected), master-link-status, slave-repl-offset, and slave-priority. Use to see which replicas are up, their replication offset (lag vs the master), and which are failover-eligible. Connects to the Sentinel on port 26379. Read-only. (SENTINEL REPLICAS, the modern name for the deprecated SLAVES, requires Redis >= 5.0.)","description":"List the replicas Sentinel has discovered for one master, each with ip:port, flags (slave/s_down/disconnected), master-link-status, slave-repl-offset, and slave-priority. Use to see which replicas are up, their replication offset (lag vs the master), and which are failover-eligible. Connects to the Sentinel on port 26379. Read-only. (SENTINEL REPLICAS, the modern name for the deprecated SLAVES, requires Redis >= 5.0.)","kind":"exec","risk":"low","side_effects":["One SENTINEL REPLICAS command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name whose replicas to list (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Replicas of master mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","REPLICAS","{{ args.master_name }}"]}},{"id":"redis.sentinel_reset","title":"SENTINEL RESET","summary":"Reset every monitored master whose name matches the glob pattern. The reset CLEARS any state for the master — including a failover in progress — and DROPS every discovered replica and peer Sentinel, so they are re-learned over the next ~10s from the current master's INFO. Use to clean up stale/removed replicas after a topology change (run on every Sentinel). A too-broad pattern (e.g. \"*\") resets all masters at once. Connects to the Sentinel on port 26379.","description":"Reset every monitored master whose name matches the glob pattern. The reset CLEARS any state for the master — including a failover in progress — and DROPS every discovered replica and peer Sentinel, so they are re-learned over the next ~10s from the current master's INFO. Use to clean up stale/removed replicas after a topology change (run on every Sentinel). A too-broad pattern (e.g. \"*\") resets all masters at once. Connects to the Sentinel on port 26379.","kind":"exec","risk":"high","side_effects":["All matching masters' discovered replicas and peer Sentinels are dropped and re-learned.","Any in-progress failover state for matching masters is cleared.","Must be run on every Sentinel to fully evict a removed replica."],"args":[{"name":"pattern","type":"string","required":true,"description":"Glob over master names; use an exact name to scope to one master.","validation":{"pattern":"^[A-Za-z0-9._*?][A-Za-z0-9._*?-]{0,127}$"}}],"examples":[{"title":"Reset one master to drop stale replicas","args":{"pattern":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","RESET","{{ args.pattern }}"]}},{"id":"redis.sentinel_sentinels","title":"SENTINEL SENTINELS","summary":"List the OTHER Sentinel instances this Sentinel knows about for a given master — each with ip:port, runid, flags, and last-ok-ping. Use to confirm the Sentinel set is fully meshed and agrees on membership when diagnosing why a failover quorum is not reached. Connects to the Sentinel on port 26379. Read-only.","description":"List the OTHER Sentinel instances this Sentinel knows about for a given master — each with ip:port, runid, flags, and last-ok-ping. Use to confirm the Sentinel set is fully meshed and agrees on membership when diagnosing why a failover quorum is not reached. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL SENTINELS command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name whose peer Sentinels to list (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Peer Sentinels for master mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","SENTINELS","{{ args.master_name }}"]}},{"id":"redis.shutdown_nosave","title":"SHUTDOWN NOSAVE","summary":"Stop the Redis process without writing an RDB. Any data not already persisted is LOST. Used only for cache-only nodes or during recovery from a corrupted state. Process exit means the host's systemd/supervisor will then restart it (or not).","description":"Stop the Redis process without writing an RDB. Any data not already persisted is LOST. Used only for cache-only nodes or during recovery from a corrupted state. Process exit means the host's systemd/supervisor will then restart it (or not).","kind":"exec","risk":"critical","side_effects":["Redis exits immediately.","In-memory data not yet persisted is lost.","Replicas detect disconnect and stop receiving updates.","Supervisor restart depends on host config."],"args":[],"examples":[{"title":"Hard stop (cache-only host)","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["SHUTDOWN","NOSAVE"]}},{"id":"redis.slowlog","title":"SLOWLOG GET","summary":"Return the last N slowlog entries (commands that exceeded the slowlog threshold). Each entry shows id, timestamp, duration (µs), command + args, client addr, and client name. Read-only. Rated medium because each entry carries the executed command with its literal arguments and the client address, which no redaction list can enumerate.","description":"Return the last N slowlog entries (commands that exceeded the slowlog threshold). Each entry shows id, timestamp, duration (µs), command + args, client addr, and client name. Read-only. Rated medium because each entry carries the executed command with its literal arguments and the client address, which no redaction list can enumerate.","kind":"exec","risk":"medium","side_effects":["Issues one SLOWLOG GET command.","No keys read or written."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"How many slowlog entries to return.","validation":{"min":1,"max":1024}}],"examples":[{"title":"Last 50 slow commands","args":{}}],"search_terms":["slow queries","client timeouts"],"command":{"binary":"redis-cli","argv":["SLOWLOG","GET","{{ args.limit }}"]}},{"id":"redis.swapdb","title":"SWAPDB","summary":"Atomically swap the contents of two logical databases. Clients connected to db i now see db j and vice versa. Used for blue/green cache rebuilds. Wrong indices flip live traffic to a stale dataset.","description":"Atomically swap the contents of two logical databases. Clients connected to db i now see db j and vice versa. Used for blue/green cache rebuilds. Wrong indices flip live traffic to a stale dataset.","kind":"exec","risk":"high","side_effects":["Two databases exchange visible contents atomically.","Connected clients immediately see the swapped dataset."],"args":[{"name":"i","type":"integer","required":true,"description":"First database index.","validation":{"min":0,"max":15}},{"name":"j","type":"integer","required":true,"description":"Second database index.","validation":{"min":0,"max":15}}],"examples":[{"title":"Swap into rebuild slot","args":{"i":0,"j":1}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["SWAPDB","{{ args.i }}","{{ args.j }}"]}},{"id":"redis.ttl_of","title":"TTL key","summary":"Show seconds until the key expires. -2 means missing, -1 means no expiry set. Use before any expiry-related troubleshooting.","description":"Show seconds until the key expires. -2 means missing, -1 means no expiry set. Use before any expiry-related troubleshooting.","kind":"exec","risk":"low","side_effects":["One TTL command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"TTL of a session","args":{"key":"session:abc123"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["TTL","{{ args.key }}"]}},{"id":"redis.type_of","title":"TYPE key","summary":"Show the datatype of one key (string, list, set, hash, zset, stream, none).","description":"Show the datatype of one key (string, list, set, hash, zset, stream, none).","kind":"exec","risk":"low","side_effects":["One TYPE command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Type of a session key","args":{"key":"session:abc123"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["TYPE","{{ args.key }}"]}},{"id":"redis.xinfo_stream","title":"XINFO STREAM","summary":"Show one stream's length, last-generated-id, groups, first/last entry. Use to confirm producers are still appending.","description":"Show one stream's length, last-generated-id, groups, first/last entry. Use to confirm producers are still appending.","kind":"exec","risk":"low","side_effects":["One XINFO STREAM command.","Read-only."],"args":[{"name":"key","type":"string","required":true,"description":"Stream key.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Inspect events stream","args":{"key":"events:audit"}}],"search_terms":["queue backed up","stream backlog","consumer lag"],"command":{"binary":"redis-cli","argv":["XINFO","STREAM","{{ args.key }}"]}},{"id":"redis.xlen","title":"XLEN","summary":"Count entries in a stream.","description":"Count entries in a stream.","kind":"exec","risk":"low","side_effects":["One XLEN command.","Read-only."],"args":[{"name":"key","type":"string","required":true,"description":"Stream key.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Length of events stream","args":{"key":"events:audit"}}],"search_terms":["queue depth","queue backed up","stream backlog"],"command":{"binary":"redis-cli","argv":["XLEN","{{ args.key }}"]}}],"previous_versions":[{"version":"0.3.15","content_hash":"sha256:820273fdbf1ed46d311a11f1fe36ecbed4366f157508c4f09802903e29afa2e6","tarball_url":"https://registry.emisar.dev/v1/packs/redis/0.3.15/820273fdbf1ed46d311a11f1fe36ecbed4366f157508c4f09802903e29afa2e6/pack.tar.gz","actions":[{"id":"redis.acl_getuser","title":"ACL GETUSER","summary":"Get the full rule listing for one ACL user — categories, commands, key patterns, channel patterns, flags. Read-only.","description":"Get the full rule listing for one ACL user — categories, commands, key patterns, channel patterns, flags. Read-only.","kind":"exec","risk":"medium","side_effects":["One ACL GETUSER command.","Read-only."],"args":[{"name":"username","type":"string","required":true,"description":"ACL username.","validation":{"pattern":"^[A-Za-z0-9_][A-Za-z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Inspect \"metrics\" user","args":{"username":"metrics"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ACL","GETUSER","{{ args.username }}"]}},{"id":"redis.acl_list","title":"ACL LIST","summary":"List all ACL users and their rules. Read-only. Use to audit access before changing a key namespace.","description":"List all ACL users and their rules. Read-only. Use to audit access before changing a key namespace.","kind":"exec","risk":"medium","side_effects":["One ACL LIST command.","Read-only."],"args":[],"examples":[{"title":"All ACL users","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ACL","LIST"]}},{"id":"redis.acl_whoami","title":"ACL WHOAMI","summary":"Show the ACL username of the current connection. Use to verify the runner credential is the expected service principal.","description":"Show the ACL username of the current connection. Use to verify the runner credential is the expected service principal.","kind":"exec","risk":"low","side_effects":["One ACL WHOAMI command.","Read-only."],"args":[],"examples":[{"title":"Connected user","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ACL","WHOAMI"]}},{"id":"redis.bgrewriteaof","title":"BGREWRITEAOF","summary":"Rewrite the AOF file in the background, compacting it to the smallest equivalent command set. Reduces AOF size and recovery time. Brief fork. Concurrent BGSAVE will queue.","description":"Rewrite the AOF file in the background, compacting it to the smallest equivalent command set. Reduces AOF size and recovery time. Brief fork. Concurrent BGSAVE will queue.","kind":"exec","risk":"medium","side_effects":["One fork; brief CPU + memory spike.","Writes a new AOF file then renames into place.","Concurrent BGSAVE will queue behind this."],"args":[],"examples":[{"title":"Compact AOF","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["BGREWRITEAOF"]}},{"id":"redis.bgsave","title":"BGSAVE","summary":"Trigger a background RDB snapshot. The fork briefly doubles RSS (copy-on-write). Returns immediately — completion shows in INFO rdb_last_bgsave_status. Concurrent BGREWRITEAOF will queue.","description":"Trigger a background RDB snapshot. The fork briefly doubles RSS (copy-on-write). Returns immediately — completion shows in INFO rdb_last_bgsave_status. Concurrent BGREWRITEAOF will queue.","kind":"exec","risk":"medium","side_effects":["One fork; brief CPU + memory spike.","Writes an RDB file to disk.","Concurrent BGREWRITEAOF will queue behind this."],"args":[],"examples":[{"title":"Trigger background snapshot","args":{}}],"search_terms":["backup now"],"command":{"binary":"redis-cli","argv":["BGSAVE"]}},{"id":"redis.client_kill","title":"CLIENT KILL","summary":"Disconnect one client by addr or by id. Use to evict a stuck client with a runaway output buffer, an abandoned subscriber, or a client exceeding the slowlog. Confirm the target via `client_list` first — killing the wrong client can disrupt a critical caller.","description":"Disconnect one client by addr or by id. Use to evict a stuck client with a runaway output buffer, an abandoned subscriber, or a client exceeding the slowlog. Confirm the target via `client_list` first — killing the wrong client can disrupt a critical caller.","kind":"exec","risk":"high","side_effects":["Forcibly closes the target connection.","In-flight commands on that connection are not replied to.","The client must reconnect."],"args":[{"name":"target","type":"string","required":true,"description":"ID like \"42\" or addr like \"10.0.0.5:53212\".","validation":{"pattern":"^[0-9a-fA-F.:]{1,64}$"}},{"name":"mode","type":"string","required":false,"default":"ADDR","description":"Whether `target` is an ADDR or an ID.","validation":{"enum":["ADDR","ID"]}}],"examples":[{"title":"Kill client by addr","args":{"mode":"ADDR","target":"10.0.0.5:53212"}},{"title":"Kill client by id","args":{"mode":"ID","target":"42"}}],"search_terms":["stuck client"],"command":{"binary":"redis-cli","argv":["CLIENT","KILL","{{ args.mode }}","{{ args.target }}"]}},{"id":"redis.client_list","title":"CLIENT LIST","summary":"Return every connected client with id, addr, name, age, idle, db, sub, psub, multi, qbuf, obl, oll, omem, cmd, fd. Use to find the client holding a long subscription, a runaway pipeline (large omem), or to identify candidate connections for CLIENT KILL.","description":"Return every connected client with id, addr, name, age, idle, db, sub, psub, multi, qbuf, obl, oll, omem, cmd, fd. Use to find the client holding a long subscription, a runaway pipeline (large omem), or to identify candidate connections for CLIENT KILL.","kind":"exec","risk":"low","side_effects":["Issues one CLIENT LIST command.","No keys read or written."],"args":[],"examples":[{"title":"List all connected clients","args":{}}],"search_terms":["too many connections","connection storm","who is connected"],"command":{"binary":"redis-cli","argv":["CLIENT","LIST"]}},{"id":"redis.client_pause","title":"CLIENT PAUSE","summary":"Pause all clients for N milliseconds. Used during safe failover windows to drain in-flight writes before flipping a master. Long pauses block all traffic — anything over 1s is a real outage. Replicas keep streaming during the pause.","description":"Pause all clients for N milliseconds. Used during safe failover windows to drain in-flight writes before flipping a master. Long pauses block all traffic — anything over 1s is a real outage. Replicas keep streaming during the pause.","kind":"exec","risk":"high","side_effects":["All clients stalled at the server side.","Pending requests buffer.","Memory may grow if clients keep sending."],"args":[{"name":"ms","type":"integer","required":true,"description":"Pause duration in milliseconds (1–10000).","validation":{"min":1,"max":10000}}],"examples":[{"title":"Pause 500ms during failover prep","args":{"ms":500}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLIENT","PAUSE","{{ args.ms }}"]}},{"id":"redis.cluster_check","title":"redis-cli --cluster check","summary":"Run `redis-cli --cluster check` from the local Redis entry point at 127.0.0.1:6379 — verifies slot coverage, master/replica health, and epoch consistency. Use after any topology change.","description":"Run `redis-cli --cluster check` from the local Redis entry point at 127.0.0.1:6379 — verifies slot coverage, master/replica health, and epoch consistency. Use after any topology change.","kind":"exec","risk":"low","side_effects":["Talks to every cluster node briefly.","Read-only."],"args":[],"examples":[{"title":"Local cluster check","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["--cluster","check","127.0.0.1:6379"]}},{"id":"redis.cluster_countkeysinslot","title":"CLUSTER COUNTKEYSINSLOT","summary":"Count keys mapped to a single hash slot. Use when a slot appears hot in monitoring to size the blast radius of a migration or to verify a tagged keyspace is collocated.","description":"Count keys mapped to a single hash slot. Use when a slot appears hot in monitoring to size the blast radius of a migration or to verify a tagged keyspace is collocated.","kind":"exec","risk":"low","side_effects":["One CLUSTER COUNTKEYSINSLOT command.","Read-only."],"args":[{"name":"slot","type":"integer","required":true,"description":"Hash slot (0–16383).","validation":{"min":0,"max":16383}}],"examples":[{"title":"Key count in slot 5000","args":{"slot":5000}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","COUNTKEYSINSLOT","{{ args.slot }}"]}},{"id":"redis.cluster_failover","title":"CLUSTER FAILOVER","summary":"Promote the connected REPLICA to master. Default mode (empty) waits for replication parity — the only safe choice during a planned failover. FORCE skips parity (use only when master is suspected dead). TAKEOVER bypasses cluster consensus entirely (split-brain recovery). Run while connected to a REPLICA, not a master.","description":"Promote the connected REPLICA to master. Default mode (empty) waits for replication parity — the only safe choice during a planned failover. FORCE skips parity (use only when master is suspected dead). TAKEOVER bypasses cluster consensus entirely (split-brain recovery). Run while connected to a REPLICA, not a master.","kind":"exec","risk":"critical","side_effects":["The connected replica becomes master.","The previous master becomes a replica.","Brief slot-ownership flip; some commands may transiently fail.","Other replicas reconfigure to follow the new master."],"args":[{"name":"mode","type":"string","required":false,"default":"","description":"Empty (safe), FORCE, or TAKEOVER.","validation":{"enum":["","FORCE","TAKEOVER"]}}],"examples":[{"title":"Safe failover from replica","args":{}},{"title":"Force failover (master suspected dead)","args":{"mode":"FORCE"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","redis-cli CLUSTER FAILOVER {{ args.mode }}"]}},{"id":"redis.cluster_forget","title":"CLUSTER FORGET","summary":"Remove a node from the connected node's cluster view for 60s. Used during node replacement. Run on every reachable node to fully evict the old member. Wrong target id produces a brief split view until gossip refreshes.","description":"Remove a node from the connected node's cluster view for 60s. Used during node replacement. Run on every reachable node to fully evict the old member. Wrong target id produces a brief split view until gossip refreshes.","kind":"exec","risk":"high","side_effects":["The connected node drops the named member from its view.","Effect lasts 60 seconds; gossip may re-discover an alive node.","Run on every node to permanently evict."],"args":[{"name":"node_id","type":"string","required":true,"description":"40-char hex node id.","validation":{"pattern":"^[a-f0-9]{40}$"}}],"examples":[{"title":"Forget a node","args":{"node_id":"07c37dfeb235213a872192d90877d0cd55635b91"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","FORGET","{{ args.node_id }}"]}},{"id":"redis.cluster_info","title":"CLUSTER INFO","summary":"Show cluster status — state ok/fail, slots assigned/ok/pfail/fail, known nodes, size, epoch, my epoch, messages sent/received.","description":"Show cluster status — state ok/fail, slots assigned/ok/pfail/fail, known nodes, size, epoch, my epoch, messages sent/received.","kind":"exec","risk":"low","side_effects":["One CLUSTER INFO command.","Read-only."],"args":[],"examples":[{"title":"Cluster health summary","args":{}}],"search_terms":["cluster down","clusterdown"],"command":{"binary":"redis-cli","argv":["CLUSTER","INFO"]}},{"id":"redis.cluster_nodes","title":"CLUSTER NODES","summary":"List the cluster nodes — id, addr, flags (master/replica/myself/fail), master id, last ping/pong, config epoch, link state, slot ranges. Use to see who owns which slot ranges and which replicas serve which masters.","description":"List the cluster nodes — id, addr, flags (master/replica/myself/fail), master id, last ping/pong, config epoch, link state, slot ranges. Use to see who owns which slot ranges and which replicas serve which masters.","kind":"exec","risk":"low","side_effects":["One CLUSTER NODES command.","Read-only."],"args":[],"examples":[{"title":"Topology view","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","NODES"]}},{"id":"redis.cluster_slots","title":"CLUSTER SLOTS","summary":"Show the slot-range → master/replica mapping. Use to confirm a given hash slot is owned by the expected shard and to see replica addresses for read traffic.","description":"Show the slot-range → master/replica mapping. Use to confirm a given hash slot is owned by the expected shard and to see replica addresses for read traffic.","kind":"exec","risk":"low","side_effects":["One CLUSTER SLOTS command.","Read-only."],"args":[],"examples":[{"title":"Slot ownership map","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CLUSTER","SLOTS"]}},{"id":"redis.command_stats","title":"INFO commandstats","summary":"Return per-command call count, total µs spent, and µs per call. Use to identify hot commands (e.g. an unexpectedly high KEYS rate or a SUBSCRIBE storm). Read-only.","description":"Return per-command call count, total µs spent, and µs per call. Use to identify hot commands (e.g. an unexpectedly high KEYS rate or a SUBSCRIBE storm). Read-only.","kind":"exec","risk":"low","side_effects":["Issues one INFO commandstats command.","No keys read or written."],"args":[],"examples":[{"title":"Per-command stats","args":{}}],"search_terms":["hot commands"],"command":{"binary":"redis-cli","argv":["INFO","commandstats"]}},{"id":"redis.config_get","title":"CONFIG GET","summary":"Read runtime config by glob pattern. Useful before any tuning conversation: confirm `maxmemory`, `maxmemory-policy`, `appendonly`, `save`, etc. Read-only. Pattern is restricted to safe globs against Redis config keys. Credential values are masked in the output — the key stays visible so you can see it is set.","description":"Read runtime config by glob pattern. Useful before any tuning conversation: confirm `maxmemory`, `maxmemory-policy`, `appendonly`, `save`, etc. Read-only. Pattern is restricted to safe globs against Redis config keys. Credential values are masked in the output — the key stays visible so you can see it is set.","kind":"exec","risk":"medium","side_effects":["Issues one CONFIG GET command.","No keys read or written.","Read-only, but the default `*` pattern returns the whole server config.","Redis owns this key space, so its credential keys are enumerable rather than guessed at. On 7.4.10 they are requirepass, masterauth, tls-key-file-pass and tls-client-key-file-pass.","Every one of those ends in a suffix the redaction rule matches. The near misses (masteruser, tls-key-file, tls-auth-clients) are a username, a path and a mode, not secrets.","That established coverage is why this is medium. A config that operators author as free text, like an nginx or Caddy dump, cannot claim it and stays high."],"args":[{"name":"pattern","type":"string","required":false,"default":"*","description":"Glob pattern (e.g. \"maxmemory*\", \"save\", \"*\").","validation":{"pattern":"^[a-zA-Z0-9_*?][a-zA-Z0-9_\\-*?]{0,63}$"}}],"examples":[{"title":"Memory-related config","args":{"pattern":"maxmemory*"}},{"title":"All persistence settings","args":{"pattern":"save"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CONFIG","GET","{{ args.pattern }}"]}},{"id":"redis.config_resetstat","title":"CONFIG RESETSTAT","summary":"Reset INFO stats counters (commandstats, keyspace hits/misses, evictions, etc.). Does NOT change keyspace data, but it DOES mutate server state by zeroing the counters — so it is risk:medium (policy-gated), like the other non-keyspace mutators (memory_purge, script_flush). Use to start a fresh measurement window.","description":"Reset INFO stats counters (commandstats, keyspace hits/misses, evictions, etc.). Does NOT change keyspace data, but it DOES mutate server state by zeroing the counters — so it is risk:medium (policy-gated), like the other non-keyspace mutators (memory_purge, script_flush). Use to start a fresh measurement window.","kind":"exec","risk":"medium","side_effects":["INFO counters zero.","No keys read or written."],"args":[],"examples":[{"title":"Reset stats","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CONFIG","RESETSTAT"]}},{"id":"redis.config_rewrite","title":"CONFIG REWRITE","summary":"Persist all runtime CONFIG SET changes back to the on-disk redis.conf. Without this, runtime overrides revert at restart.","description":"Persist all runtime CONFIG SET changes back to the on-disk redis.conf. Without this, runtime overrides revert at restart.","kind":"exec","risk":"medium","side_effects":["Rewrites redis.conf in place (preserves comments, updates values).","No keyspace changes."],"args":[],"examples":[{"title":"Persist runtime config","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["CONFIG","REWRITE"]}},{"id":"redis.config_set","title":"CONFIG SET","summary":"Change one runtime config parameter. Effects are immediate and may include eviction policy, persistence mode, replication behavior. Combine with config_rewrite to persist. Value pattern is restricted to safe characters.","description":"Change one runtime config parameter. Effects are immediate and may include eviction policy, persistence mode, replication behavior. Combine with config_rewrite to persist. Value pattern is restricted to safe characters.","kind":"exec","risk":"high","side_effects":["Runtime behavior changes immediately.","Some parameters affect persistence, replication, eviction.","Not persisted across restart without CONFIG REWRITE."],"args":[{"name":"parameter","type":"string","required":true,"description":"Config parameter name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"value","type":"string","required":true,"description":"New value (limited charset).","validation":{"pattern":"^[a-zA-Z0-9_./ %:][a-zA-Z0-9_\\-./ %:]{0,255}$"}}],"examples":[{"title":"Raise maxmemory","args":{"parameter":"maxmemory","value":"4gb"}}],"search_terms":["set maxmemory","change eviction policy"],"command":{"binary":"redis-cli","argv":["CONFIG","SET","{{ args.parameter }}","{{ args.value }}"]}},{"id":"redis.dbsize","title":"DBSIZE","summary":"Return the number of keys in the currently selected database. O(1). Read-only. Use as a sanity check before running operations that scan the keyspace.","description":"Return the number of keys in the currently selected database. O(1). Read-only. Use as a sanity check before running operations that scan the keyspace.","kind":"exec","risk":"low","side_effects":["Issues one DBSIZE command.","No keys read or written."],"args":[{"name":"db","type":"integer","required":false,"default":0,"description":"Logical database index.","validation":{"min":0,"max":15}}],"examples":[{"title":"Key count in DB 0","args":{}}],"search_terms":["key count","how many keys"],"command":{"binary":"redis-cli","argv":["-n","{{ args.db }}","DBSIZE"]}},{"id":"redis.flush_db","title":"FLUSHDB (single database)","summary":"Delete every key in one logical database. Irreversible. Use only on caches and only when you know there is no replication consumer that treats an empty DB as a fault. ASYNC mode returns immediately and drops the data in a background thread; SYNC blocks until done. Never use against production user data — this exists for cache resets and dev environments.","description":"Delete every key in one logical database. Irreversible. Use only on caches and only when you know there is no replication consumer that treats an empty DB as a fault. ASYNC mode returns immediately and drops the data in a background thread; SYNC blocks until done. Never use against production user data — this exists for cache resets and dev environments.","kind":"exec","risk":"critical","side_effects":["All keys in the selected database are deleted.","Replicas FLUSHDB in turn.","No way to recover except by restore."],"args":[{"name":"db","type":"integer","required":true,"description":"Database index to flush.","validation":{"min":0,"max":15}},{"name":"mode","type":"string","required":false,"default":"ASYNC","description":"Run synchronously or async.","validation":{"enum":["SYNC","ASYNC"]}}],"examples":[{"title":"Async flush of cache DB 2","args":{"db":2,"mode":"ASYNC"}}],"search_terms":["clear cache","empty cache"],"command":{"binary":"redis-cli","argv":["-n","{{ args.db }}","FLUSHDB","{{ args.mode }}"]}},{"id":"redis.flushall","title":"FLUSHALL","summary":"Delete EVERY key from EVERY database. Irreversible. Replicas FLUSHALL in turn. Only use on caches that can be cold-rebuilt.","description":"Delete EVERY key from EVERY database. Irreversible. Replicas FLUSHALL in turn. Only use on caches that can be cold-rebuilt.","kind":"exec","risk":"critical","side_effects":["All databases emptied.","Replicas wipe in turn.","No recovery except restore."],"args":[{"name":"mode","type":"string","required":false,"default":"ASYNC","description":"SYNC (block) or ASYNC (return, drop in background).","validation":{"enum":["SYNC","ASYNC"]}}],"examples":[{"title":"Async wipe all DBs","args":{}}],"search_terms":["clear all caches"],"command":{"binary":"redis-cli","argv":["FLUSHALL","{{ args.mode }}"]}},{"id":"redis.info","title":"Redis INFO section","summary":"Run `INFO <section>` and return the raw text. Sections: server, clients, memory, persistence, stats, replication, cpu, commandstats, latencystats, cluster, keyspace, errorstats, all. Read-only.","description":"Run `INFO <section>` and return the raw text. Sections: server, clients, memory, persistence, stats, replication, cpu, commandstats, latencystats, cluster, keyspace, errorstats, all. Read-only.","kind":"exec","risk":"low","side_effects":["Issues one INFO command.","No keys read or written."],"args":[{"name":"section","type":"string","required":false,"default":"default","description":"INFO section.","validation":{"enum":["default","all","server","clients","memory","persistence","stats","replication","cpu","commandstats","latencystats","cluster","keyspace","errorstats"]}}],"examples":[{"title":"Default INFO","args":{}},{"title":"Memory-only INFO","args":{"section":"memory"}}],"search_terms":["cache health","cache unhealthy","hit rate","evictions"],"command":{"binary":"redis-cli","argv":["INFO","{{ args.section }}"]}},{"id":"redis.lastsave","title":"LASTSAVE","summary":"Show the Unix timestamp of the last successful background save (RDB). Use to confirm the persistence schedule is firing.","description":"Show the Unix timestamp of the last successful background save (RDB). Use to confirm the persistence schedule is firing.","kind":"exec","risk":"low","side_effects":["One LASTSAVE command.","Read-only."],"args":[],"examples":[{"title":"Last RDB timestamp","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["LASTSAVE"]}},{"id":"redis.latency","title":"LATENCY LATEST + HISTORY","summary":"Run `LATENCY LATEST` to summarize per-event latency spikes (fork, AOF write, expire, eviction, command, etc.). Requires `latency-monitor-threshold` to be set non-zero in redis.conf; if it isn't, the output is empty and that is a configuration finding worth reporting. Read-only.","description":"Run `LATENCY LATEST` to summarize per-event latency spikes (fork, AOF write, expire, eviction, command, etc.). Requires `latency-monitor-threshold` to be set non-zero in redis.conf; if it isn't, the output is empty and that is a configuration finding worth reporting. Read-only.","kind":"exec","risk":"low","side_effects":["Issues one LATENCY LATEST command.","No keys read or written."],"args":[],"examples":[{"title":"Show latest latency events","args":{}}],"search_terms":["intermittent stalls"],"command":{"binary":"redis-cli","argv":["LATENCY","LATEST"]}},{"id":"redis.latency_history","title":"LATENCY HISTORY","summary":"Show per-event latency time series (e.g. fork, aof-write, expire). Use after LATENCY LATEST to drill into one event class.","description":"Show per-event latency time series (e.g. fork, aof-write, expire). Use after LATENCY LATEST to drill into one event class.","kind":"exec","risk":"low","side_effects":["One LATENCY HISTORY command.","Read-only."],"args":[{"name":"event","type":"string","required":true,"description":"Event name from LATENCY LATEST.","validation":{"pattern":"^[a-z0-9][a-z0-9\\-_]{0,31}$"}}],"examples":[{"title":"Fork latency history","args":{"event":"fork"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["LATENCY","HISTORY","{{ args.event }}"]}},{"id":"redis.memory_doctor","title":"MEMORY DOCTOR","summary":"Run the built-in memory advisor. Returns a human-readable summary of suspected issues (fragmentation, oversized clients, large peak vs current).","description":"Run the built-in memory advisor. Returns a human-readable summary of suspected issues (fragmentation, oversized clients, large peak vs current).","kind":"exec","risk":"low","side_effects":["One MEMORY DOCTOR command.","Read-only."],"args":[],"examples":[{"title":"Memory advisor","args":{}}],"search_terms":["cache health","cache unhealthy","memory fragmentation"],"command":{"binary":"redis-cli","argv":["MEMORY","DOCTOR"]}},{"id":"redis.memory_purge","title":"MEMORY PURGE","summary":"Ask jemalloc to release unused memory back to the OS. Use after a large eviction or DEL spike when RSS hasn't dropped despite used_memory falling. Brief allocator pause possible.","description":"Ask jemalloc to release unused memory back to the OS. Use after a large eviction or DEL spike when RSS hasn't dropped despite used_memory falling. Brief allocator pause possible.","kind":"exec","risk":"medium","side_effects":["Brief allocator pause.","RSS may drop afterwards.","Does not affect keys."],"args":[],"examples":[{"title":"Release jemalloc-cached memory","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["MEMORY","PURGE"]}},{"id":"redis.memory_stats","title":"MEMORY STATS","summary":"Run `MEMORY STATS`. Returns the detailed memory accounting (allocator stats, fragmentation, peak, overheads, replication backlog, client and AOF buffers). Read-only. Use to diagnose OOM warnings before resizing.","description":"Run `MEMORY STATS`. Returns the detailed memory accounting (allocator stats, fragmentation, peak, overheads, replication backlog, client and AOF buffers). Read-only. Use to diagnose OOM warnings before resizing.","kind":"exec","risk":"low","side_effects":["Issues one MEMORY STATS command.","No keys read or written."],"args":[],"examples":[{"title":"Detailed memory accounting","args":{}}],"search_terms":["memory breakdown","oom warnings"],"command":{"binary":"redis-cli","argv":["MEMORY","STATS"]}},{"id":"redis.memory_usage","title":"MEMORY USAGE key","summary":"Show bytes used by a single key (estimate, including value and internal overhead). Use to find a known big-value culprit before a deletion conversation.","description":"Show bytes used by a single key (estimate, including value and internal overhead). Use to find a known big-value culprit before a deletion conversation.","kind":"exec","risk":"low","side_effects":["One MEMORY USAGE command.","Reads metadata but not the value."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Size of a session key","args":{"key":"session:abc123"}}],"search_terms":["big key","key size"],"command":{"binary":"redis-cli","argv":["MEMORY","USAGE","{{ args.key }}"]}},{"id":"redis.object_encoding","title":"OBJECT ENCODING key","summary":"Show the internal encoding of one value (ziplist, hashtable, intset, listpack, quicklist, embstr, raw, skiplist). Use to confirm a structure is in its compact form before tuning size limits.","description":"Show the internal encoding of one value (ziplist, hashtable, intset, listpack, quicklist, embstr, raw, skiplist). Use to confirm a structure is in its compact form before tuning size limits.","kind":"exec","risk":"low","side_effects":["One OBJECT ENCODING command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Encoding of a hash","args":{"key":"user:42"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","ENCODING","{{ args.key }}"]}},{"id":"redis.object_freq","title":"OBJECT FREQ key","summary":"Show the LFU access-frequency counter for the key. Requires an LFU maxmemory-policy. Use to compare access patterns across a candidate eviction set.","description":"Show the LFU access-frequency counter for the key. Requires an LFU maxmemory-policy. Use to compare access patterns across a candidate eviction set.","kind":"exec","risk":"low","side_effects":["One OBJECT FREQ command.","Read-only metadata; does not bump the frequency counter."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Access frequency","args":{"key":"user:42"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","FREQ","{{ args.key }}"]}},{"id":"redis.object_idletime","title":"OBJECT IDLETIME key","summary":"Show seconds since the key was last accessed. Requires an LRU maxmemory-policy. Use to identify cold keys for manual eviction.","description":"Show seconds since the key was last accessed. Requires an LRU maxmemory-policy. Use to identify cold keys for manual eviction.","kind":"exec","risk":"low","side_effects":["One OBJECT IDLETIME command.","Read-only metadata; does not bump LRU age."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"How cold is this key?","args":{"key":"user:42"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","IDLETIME","{{ args.key }}"]}},{"id":"redis.object_refcount","title":"OBJECT REFCOUNT key","summary":"Show the reference count for a value. Shared integers report INT_MAX; every other value reports 1. Use to confirm the shared-integer optimization is hitting (or not).","description":"Show the reference count for a value. Shared integers report INT_MAX; every other value reports 1. Use to confirm the shared-integer optimization is hitting (or not).","kind":"exec","risk":"low","side_effects":["One OBJECT REFCOUNT command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Refcount of a counter","args":{"key":"stats:requests"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["OBJECT","REFCOUNT","{{ args.key }}"]}},{"id":"redis.pubsub_channels","title":"PUBSUB CHANNELS","summary":"List active pub/sub channels matching the optional pattern. Useful to see which event streams a service is producing.","description":"List active pub/sub channels matching the optional pattern. Useful to see which event streams a service is producing.","kind":"exec","risk":"low","side_effects":["One PUBSUB CHANNELS command.","Read-only."],"args":[{"name":"pattern","type":"string","required":false,"default":"*","description":"Glob pattern.","validation":{"pattern":"^[A-Za-z0-9_:.*?{}@#/=+][A-Za-z0-9_:.\\-*?{}@#/=+]{0,255}$"}}],"examples":[{"title":"All active channels","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["PUBSUB","CHANNELS","{{ args.pattern }}"]}},{"id":"redis.pubsub_numsub","title":"PUBSUB NUMSUB","summary":"Count subscribers on a channel. Useful before tearing down a producer.","description":"Count subscribers on a channel. Useful before tearing down a producer.","kind":"exec","risk":"low","side_effects":["One PUBSUB NUMSUB command.","Read-only."],"args":[{"name":"channel","type":"string","required":true,"description":"Channel name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,255}$"}}],"examples":[{"title":"Subscribers on events.user","args":{"channel":"events.user"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["PUBSUB","NUMSUB","{{ args.channel }}"]}},{"id":"redis.randomkey","title":"RANDOMKEY","summary":"Return a random key from the current database (or nil if empty). Useful for sampling key shapes.","description":"Return a random key from the current database (or nil if empty). Useful for sampling key shapes.","kind":"exec","risk":"low","side_effects":["One RANDOMKEY command.","Read-only."],"args":[],"examples":[{"title":"Sample one key","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["RANDOMKEY"]}},{"id":"redis.replicaof","title":"REPLICAOF","summary":"Reconfigure replication. REPLICAOF NO ONE promotes this node to master (used in unmanaged failover). REPLICAOF host port reassigns this node as a replica of host:port and triggers a full sync — the local dataset is REPLACED. Misuse can wipe live data.","description":"Reconfigure replication. REPLICAOF NO ONE promotes this node to master (used in unmanaged failover). REPLICAOF host port reassigns this node as a replica of host:port and triggers a full sync — the local dataset is REPLACED. Misuse can wipe live data.","kind":"exec","risk":"critical","side_effects":["Replication topology changes immediately.","If becoming a replica: local dataset is replaced by the new master's snapshot.","If promoted to master: existing replicas of the old master may still follow it."],"args":[{"name":"host","type":"string","required":true,"description":"New master host, or the literal \"NO\" to demote.","validation":{"pattern":"^[a-zA-Z0-9._][a-zA-Z0-9._\\-]{0,252}$"}},{"name":"port","type":"string","required":true,"description":"New master port (1-65535), or the literal \"ONE\" if host is \"NO\".","validation":{"pattern":"^([1-9][0-9]{0,4}|ONE)$"}}],"examples":[{"title":"Promote to master","args":{"host":"NO","port":"ONE"}},{"title":"Become replica of 10.0.0.5:6379","args":{"host":"10.0.0.5","port":"6379"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["REPLICAOF","{{ args.host }}","{{ args.port }}"]}},{"id":"redis.role","title":"ROLE","summary":"Report whether this Redis is master, replica, or sentinel. Master shows replication offset and connected replicas; replica shows master addr + sync state. Use before any write-path troubleshooting.","description":"Report whether this Redis is master, replica, or sentinel. Master shows replication offset and connected replicas; replica shows master addr + sync state. Use before any write-path troubleshooting.","kind":"exec","risk":"low","side_effects":["One ROLE command.","Read-only."],"args":[],"examples":[{"title":"Replication role","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["ROLE"]}},{"id":"redis.scan","title":"SCAN cursor MATCH COUNT","summary":"Show one SCAN page. Returns next-cursor + up to COUNT keys matching MATCH. Safe for prod — never blocks. Use to enumerate a hot namespace without KEYS.","description":"Show one SCAN page. Returns next-cursor + up to COUNT keys matching MATCH. Safe for prod — never blocks. Use to enumerate a hot namespace without KEYS.","kind":"exec","risk":"low","side_effects":["One SCAN command.","Read-only metadata; values are not fetched."],"args":[{"name":"cursor","type":"string","required":false,"default":"0","description":"Cursor (start with \"0\").","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"match","type":"string","required":false,"default":"*","description":"Glob pattern.","validation":{"pattern":"^[A-Za-z0-9_:.*?{}@#/=+][A-Za-z0-9_:.\\-*?{}@#/=+]{0,255}$"}},{"name":"count","type":"integer","required":false,"default":100,"description":"Server hint for batch size.","validation":{"min":1,"max":10000}}],"examples":[{"title":"First page of session keys","args":{"count":200,"match":"session:*"}}],"search_terms":["list keys","find keys by pattern"],"command":{"binary":"redis-cli","argv":["SCAN","{{ args.cursor }}","MATCH","{{ args.match }}","COUNT","{{ args.count }}"]}},{"id":"redis.script_flush","title":"SCRIPT FLUSH","summary":"Drop all cached EVAL scripts (server-side Lua). Clients using EVAL repopulate naturally; clients using EVALSHA hit NOSCRIPT until they re-cache.","description":"Drop all cached EVAL scripts (server-side Lua). Clients using EVAL repopulate naturally; clients using EVALSHA hit NOSCRIPT until they re-cache.","kind":"exec","risk":"medium","side_effects":["Script cache cleared.","Brief NOSCRIPT errors expected on EVALSHA callers."],"args":[{"name":"mode","type":"string","required":false,"default":"ASYNC","description":"SYNC (block) or ASYNC (return immediately).","validation":{"enum":["SYNC","ASYNC"]}}],"examples":[{"title":"Async script flush","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["SCRIPT","FLUSH","{{ args.mode }}"]}},{"id":"redis.sentinel_ckquorum","title":"SENTINEL CKQUORUM","summary":"Check whether enough Sentinels are reachable to BOTH reach the failover quorum AND form the majority needed to authorize a failover for the named master. The canonical pre-failover health check — returns OK with the counts, or an error if a failover could not currently proceed. Connects to the Sentinel on port 26379. Read-only.","description":"Check whether enough Sentinels are reachable to BOTH reach the failover quorum AND form the majority needed to authorize a failover for the named master. The canonical pre-failover health check — returns OK with the counts, or an error if a failover could not currently proceed. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL CKQUORUM command on the local Sentinel (port 26379).","No Sentinel state changed, no failover triggered."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name to check quorum for (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Can mymaster be failed over right now?","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","CKQUORUM","{{ args.master_name }}"]}},{"id":"redis.sentinel_failover","title":"SENTINEL FAILOVER","summary":"Force a failover for the named master as if it were unreachable, WITHOUT asking the other Sentinels for agreement (a new configuration is still published so the peers update). Promotes a replica to master and reconfigures the rest to follow it. This is a manual, operator-initiated failover — use for a planned switchover or to recover when automatic failover is stuck. Connects to the Sentinel on port 26379.","description":"Force a failover for the named master as if it were unreachable, WITHOUT asking the other Sentinels for agreement (a new configuration is still published so the peers update). Promotes a replica to master and reconfigures the rest to follow it. This is a manual, operator-initiated failover — use for a planned switchover or to recover when automatic failover is stuck. Connects to the Sentinel on port 26379.","kind":"exec","risk":"high","side_effects":["The named master is failed over; a replica is promoted to master.","Remaining replicas are reconfigured to replicate from the new master.","The new topology is published to all Sentinels; clients are redirected.","Brief write unavailability during the promotion."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name to fail over (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Force failover of mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","FAILOVER","{{ args.master_name }}"]}},{"id":"redis.sentinel_get_master_addr","title":"SENTINEL GET-MASTER-ADDR-BY-NAME","summary":"Return the ip and port Sentinel currently believes is the master for the named set. During or just after a failover this returns the PROMOTED replica's address — so it is the authoritative answer to \"who is the master right now?\" Compare against ROLE on each node to detect split-brain. Connects to the Sentinel on port 26379. Read-only.","description":"Return the ip and port Sentinel currently believes is the master for the named set. During or just after a failover this returns the PROMOTED replica's address — so it is the authoritative answer to \"who is the master right now?\" Compare against ROLE on each node to detect split-brain. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL GET-MASTER-ADDR-BY-NAME command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name to resolve (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Current master address for mymaster","args":{"master_name":"mymaster"}}],"search_terms":["who is the master","current master"],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","GET-MASTER-ADDR-BY-NAME","{{ args.master_name }}"]}},{"id":"redis.sentinel_info","title":"Sentinel INFO","summary":"Run INFO against the Sentinel process itself (port 26379) and return the raw text, including the `sentinel` section: sentinel_masters, sentinel_running_scripts, sentinel_tilt, and a master0..N line per monitored master (name, status, address, slaves, sentinels). Use to read the Sentinel's own health — e.g. whether it is in TILT mode. Read-only.","description":"Run INFO against the Sentinel process itself (port 26379) and return the raw text, including the `sentinel` section: sentinel_masters, sentinel_running_scripts, sentinel_tilt, and a master0..N line per monitored master (name, status, address, slaves, sentinels). Use to read the Sentinel's own health — e.g. whether it is in TILT mode. Read-only.","kind":"exec","risk":"low","side_effects":["One INFO command on the local Sentinel (port 26379).","No keys read or written; no Sentinel state changed."],"args":[{"name":"section","type":"string","required":false,"default":"default","description":"INFO section.","validation":{"enum":["default","all","server","clients","cpu","stats","sentinel"]}}],"examples":[{"title":"Sentinel INFO (default)","args":{}},{"title":"Sentinel section only","args":{"section":"sentinel"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","INFO","{{ args.section }}"]}},{"id":"redis.sentinel_is_master_down","title":"SENTINEL IS-MASTER-DOWN-BY-ADDR","summary":"Ask this Sentinel whether the master at ip:port is subjectively down from its point of view. Primarily an internal failover-consensus command, but useful read-only forensics when investigating WHY an objective-down (ODOWN) or failover did or did not fire. Always sends epoch 0 and run id \"*\", Redis's non-voting form. Connects to the Sentinel on port 26379. Read-only.","description":"Ask this Sentinel whether the master at ip:port is subjectively down from its point of view. Primarily an internal failover-consensus command, but useful read-only forensics when investigating WHY an objective-down (ODOWN) or failover did or did not fire. Always sends epoch 0 and run id \"*\", Redis's non-voting form. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL IS-MASTER-DOWN-BY-ADDR command on the local Sentinel (port 26379).","Fixed to epoch 0 and run id \"*\", so it cannot advance the election epoch or request a leader vote."],"args":[{"name":"ip","type":"string","required":true,"description":"Master IPv4/IPv6 address as Sentinel knows it.","validation":{"pattern":"^[0-9a-fA-F.:]{2,45}$"}},{"name":"port","type":"string","required":true,"description":"Master port (1-65535).","validation":{"pattern":"^[1-9][0-9]{0,4}$"}}],"examples":[{"title":"Is the master at 10.0.0.5:6379 down from this Sentinel's view?","args":{"ip":"10.0.0.5","port":"6379"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","IS-MASTER-DOWN-BY-ADDR","{{ args.ip }}","{{ args.port }}","0","*"]}},{"id":"redis.sentinel_master","title":"SENTINEL MASTER","summary":"Show the full state of one monitored master by its configured name (e.g. \"mymaster\") — ip:port, flags, quorum, num-slaves, num-other-sentinels, down-after-milliseconds, last-ping. Use to confirm a specific master's view and whether the configured quorum is met. Connects to the Sentinel on port 26379. Read-only.","description":"Show the full state of one monitored master by its configured name (e.g. \"mymaster\") — ip:port, flags, quorum, num-slaves, num-other-sentinels, down-after-milliseconds, last-ping. Use to confirm a specific master's view and whether the configured quorum is met. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL MASTER command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name Sentinel monitors (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"State of master mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","MASTER","{{ args.master_name }}"]}},{"id":"redis.sentinel_masters","title":"SENTINEL MASTERS","summary":"List every master this Sentinel monitors with full state — name, ip:port, quorum, flags (master/o_down/s_down), num-slaves, num-other-sentinels. Connects to the Sentinel on port 26379. The first stop when mapping a replicas+Sentinel topology. Read-only.","description":"List every master this Sentinel monitors with full state — name, ip:port, quorum, flags (master/o_down/s_down), num-slaves, num-other-sentinels. Connects to the Sentinel on port 26379. The first stop when mapping a replicas+Sentinel topology. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL MASTERS command on the local Sentinel (port 26379).","No Sentinel state changed, no failover triggered."],"args":[],"examples":[{"title":"All monitored masters","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","MASTERS"]}},{"id":"redis.sentinel_replicas","title":"SENTINEL REPLICAS","summary":"List the replicas Sentinel has discovered for one master, each with ip:port, flags (slave/s_down/disconnected), master-link-status, slave-repl-offset, and slave-priority. Use to see which replicas are up, their replication offset (lag vs the master), and which are failover-eligible. Connects to the Sentinel on port 26379. Read-only. (SENTINEL REPLICAS, the modern name for the deprecated SLAVES, requires Redis >= 5.0.)","description":"List the replicas Sentinel has discovered for one master, each with ip:port, flags (slave/s_down/disconnected), master-link-status, slave-repl-offset, and slave-priority. Use to see which replicas are up, their replication offset (lag vs the master), and which are failover-eligible. Connects to the Sentinel on port 26379. Read-only. (SENTINEL REPLICAS, the modern name for the deprecated SLAVES, requires Redis >= 5.0.)","kind":"exec","risk":"low","side_effects":["One SENTINEL REPLICAS command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name whose replicas to list (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Replicas of master mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","REPLICAS","{{ args.master_name }}"]}},{"id":"redis.sentinel_reset","title":"SENTINEL RESET","summary":"Reset every monitored master whose name matches the glob pattern. The reset CLEARS any state for the master — including a failover in progress — and DROPS every discovered replica and peer Sentinel, so they are re-learned over the next ~10s from the current master's INFO. Use to clean up stale/removed replicas after a topology change (run on every Sentinel). A too-broad pattern (e.g. \"*\") resets all masters at once. Connects to the Sentinel on port 26379.","description":"Reset every monitored master whose name matches the glob pattern. The reset CLEARS any state for the master — including a failover in progress — and DROPS every discovered replica and peer Sentinel, so they are re-learned over the next ~10s from the current master's INFO. Use to clean up stale/removed replicas after a topology change (run on every Sentinel). A too-broad pattern (e.g. \"*\") resets all masters at once. Connects to the Sentinel on port 26379.","kind":"exec","risk":"high","side_effects":["All matching masters' discovered replicas and peer Sentinels are dropped and re-learned.","Any in-progress failover state for matching masters is cleared.","Must be run on every Sentinel to fully evict a removed replica."],"args":[{"name":"pattern","type":"string","required":true,"description":"Glob over master names; use an exact name to scope to one master.","validation":{"pattern":"^[A-Za-z0-9._*?][A-Za-z0-9._*?-]{0,127}$"}}],"examples":[{"title":"Reset one master to drop stale replicas","args":{"pattern":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","RESET","{{ args.pattern }}"]}},{"id":"redis.sentinel_sentinels","title":"SENTINEL SENTINELS","summary":"List the OTHER Sentinel instances this Sentinel knows about for a given master — each with ip:port, runid, flags, and last-ok-ping. Use to confirm the Sentinel set is fully meshed and agrees on membership when diagnosing why a failover quorum is not reached. Connects to the Sentinel on port 26379. Read-only.","description":"List the OTHER Sentinel instances this Sentinel knows about for a given master — each with ip:port, runid, flags, and last-ok-ping. Use to confirm the Sentinel set is fully meshed and agrees on membership when diagnosing why a failover quorum is not reached. Connects to the Sentinel on port 26379. Read-only.","kind":"exec","risk":"low","side_effects":["One SENTINEL SENTINELS command on the local Sentinel (port 26379).","No Sentinel state changed."],"args":[{"name":"master_name","type":"string","required":true,"description":"Configured master name whose peer Sentinels to list (e.g. \"mymaster\").","validation":{"pattern":"^[A-Za-z0-9._][A-Za-z0-9._-]{0,127}$"}}],"examples":[{"title":"Peer Sentinels for master mymaster","args":{"master_name":"mymaster"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["-p","26379","SENTINEL","SENTINELS","{{ args.master_name }}"]}},{"id":"redis.shutdown_nosave","title":"SHUTDOWN NOSAVE","summary":"Stop the Redis process without writing an RDB. Any data not already persisted is LOST. Used only for cache-only nodes or during recovery from a corrupted state. Process exit means the host's systemd/supervisor will then restart it (or not).","description":"Stop the Redis process without writing an RDB. Any data not already persisted is LOST. Used only for cache-only nodes or during recovery from a corrupted state. Process exit means the host's systemd/supervisor will then restart it (or not).","kind":"exec","risk":"critical","side_effects":["Redis exits immediately.","In-memory data not yet persisted is lost.","Replicas detect disconnect and stop receiving updates.","Supervisor restart depends on host config."],"args":[],"examples":[{"title":"Hard stop (cache-only host)","args":{}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["SHUTDOWN","NOSAVE"]}},{"id":"redis.slowlog","title":"SLOWLOG GET","summary":"Return the last N slowlog entries (commands that exceeded the slowlog threshold). Each entry shows id, timestamp, duration (µs), command + args, client addr, and client name. Read-only.","description":"Return the last N slowlog entries (commands that exceeded the slowlog threshold). Each entry shows id, timestamp, duration (µs), command + args, client addr, and client name. Read-only.","kind":"exec","risk":"low","side_effects":["Issues one SLOWLOG GET command.","No keys read or written."],"args":[{"name":"limit","type":"integer","required":false,"default":50,"description":"How many slowlog entries to return.","validation":{"min":1,"max":1024}}],"examples":[{"title":"Last 50 slow commands","args":{}}],"search_terms":["slow queries","client timeouts"],"command":{"binary":"redis-cli","argv":["SLOWLOG","GET","{{ args.limit }}"]}},{"id":"redis.swapdb","title":"SWAPDB","summary":"Atomically swap the contents of two logical databases. Clients connected to db i now see db j and vice versa. Used for blue/green cache rebuilds. Wrong indices flip live traffic to a stale dataset.","description":"Atomically swap the contents of two logical databases. Clients connected to db i now see db j and vice versa. Used for blue/green cache rebuilds. Wrong indices flip live traffic to a stale dataset.","kind":"exec","risk":"high","side_effects":["Two databases exchange visible contents atomically.","Connected clients immediately see the swapped dataset."],"args":[{"name":"i","type":"integer","required":true,"description":"First database index.","validation":{"min":0,"max":15}},{"name":"j","type":"integer","required":true,"description":"Second database index.","validation":{"min":0,"max":15}}],"examples":[{"title":"Swap into rebuild slot","args":{"i":0,"j":1}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["SWAPDB","{{ args.i }}","{{ args.j }}"]}},{"id":"redis.ttl_of","title":"TTL key","summary":"Show seconds until the key expires. -2 means missing, -1 means no expiry set. Use before any expiry-related troubleshooting.","description":"Show seconds until the key expires. -2 means missing, -1 means no expiry set. Use before any expiry-related troubleshooting.","kind":"exec","risk":"low","side_effects":["One TTL command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"TTL of a session","args":{"key":"session:abc123"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["TTL","{{ args.key }}"]}},{"id":"redis.type_of","title":"TYPE key","summary":"Show the datatype of one key (string, list, set, hash, zset, stream, none).","description":"Show the datatype of one key (string, list, set, hash, zset, stream, none).","kind":"exec","risk":"low","side_effects":["One TYPE command.","Read-only metadata."],"args":[{"name":"key","type":"string","required":true,"description":"Key name.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Type of a session key","args":{"key":"session:abc123"}}],"search_terms":[],"command":{"binary":"redis-cli","argv":["TYPE","{{ args.key }}"]}},{"id":"redis.xinfo_stream","title":"XINFO STREAM","summary":"Show one stream's length, last-generated-id, groups, first/last entry. Use to confirm producers are still appending.","description":"Show one stream's length, last-generated-id, groups, first/last entry. Use to confirm producers are still appending.","kind":"exec","risk":"low","side_effects":["One XINFO STREAM command.","Read-only."],"args":[{"name":"key","type":"string","required":true,"description":"Stream key.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Inspect events stream","args":{"key":"events:audit"}}],"search_terms":["queue backed up","stream backlog","consumer lag"],"command":{"binary":"redis-cli","argv":["XINFO","STREAM","{{ args.key }}"]}},{"id":"redis.xlen","title":"XLEN","summary":"Count entries in a stream.","description":"Count entries in a stream.","kind":"exec","risk":"low","side_effects":["One XLEN command.","Read-only."],"args":[{"name":"key","type":"string","required":true,"description":"Stream key.","validation":{"pattern":"^[A-Za-z0-9_:.{}@#/=+][A-Za-z0-9_:.\\-{}@#/=+]{0,511}$"}}],"examples":[{"title":"Length of events stream","args":{"key":"events:audit"}}],"search_terms":["queue depth","queue backed up","stream backlog"],"command":{"binary":"redis-cli","argv":["XLEN","{{ args.key }}"]}}]}],"retired_below":"0.3.15"},{"id":"rke2","name":"RKE2 cluster (host-level)","version":"0.2.3","description":"RKE2-specific host introspection that kubectl can't give you — embedded-etcd live health (etcdctl endpoint health/status) and snapshot history, node certificate expiry, and the RKE2-bundled containerd via crictl (containers, pods, images). Runs on an RKE2 server node. Generic Kubernetes API reads are in the kubernetes pack; rke2-server / rke2-agent unit status and logs are covered by the linux-core / systemd-deep packs (systemctl status rke2-server, journalctl -u rke2-server).","vendor":"emisar","homepage":"https://emisar.dev/packs/rke2","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/rke2","content_hash":"sha256:3387d266fcc2f072d80fe6cea64e75076e396d691ee47a5859eb8eb510e8be87","tarball_url":"https://registry.emisar.dev/v1/packs/rke2/0.2.3/3387d266fcc2f072d80fe6cea64e75076e396d691ee47a5859eb8eb510e8be87/pack.tar.gz","requires":{"os":["linux"],"binaries":["rke2"]},"detect":{"binaries":["rke2"],"processes":["rke2"],"ports":[]},"setup":{"summary":"Runs on an RKE2 server node, as root (etcd-snapshot, certificate check, and crictl — including the etcd_health crictl exec — all need root). rke2 reads `/etc/rancher/rke2/config.yaml` by default; crictl talks to the RKE2 containerd socket via CRI_CONFIG_FILE.","notes":["Binary-path exception: RKE2 does not add `/var/lib/rancher/rke2/bin` to PATH, so crictl is invoked by its absolute path inside a /bin/sh command (the same absolute-path-in-a-shell-pipeline pattern other read actions use). rke2 itself installs to `/usr/local/bin` and is invoked bare.","On an agent-only node there is no etcd and no rke2 server cert set, so etcd_health / etcd_snapshot_list / certificate_check will not return server data.","etcd_health: RKE2 ships no etcdctl on the host PATH, so the action runs the etcdctl already inside the running etcd static-pod container (resolved via crictl), authenticating to https://127.0.0.1:2379 with this node's own etcd CA + server-client cert under /var/lib/rancher/rke2/server/tls/etcd/. Cert filenames verified against a live RKE2 v1.35.x server (server-ca.crt + server-client.crt/.key) and the kube-apiserver's own --etcd-* flags. Pair with etcd_snapshot_list (backups current?) and kubernetes.control_plane_health (/readyz)."],"host_access":[{"actions":["rke2.etcd_health","rke2.etcd_snapshot_list","rke2.certificate_check","rke2.crictl_ps","rke2.crictl_pods","rke2.crictl_images"],"requirement":"Read RKE2 server credentials, containerd, and embedded etcd state as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-rke2-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. These actions can read the RKE2 server's client keys and control its container runtime despite being read-only."}]}],"verify":"rke2.certificate_check"},"actions":[{"id":"rke2.certificate_check","title":"Check RKE2 certificate expiry (rke2 certificate check)","summary":"Show per-certificate subject, status, and expiry date for this node's RKE2 certs. RKE2 leaf certs default to 365 days and auto-renew on restart within 90 days of expiry; this surfaces a node whose certs are about to lapse. Read-only.","description":"Show per-certificate subject, status, and expiry date for this node's RKE2 certs. RKE2 leaf certs default to 365 days and auto-renew on restart within 90 days of expiry; this surfaces a node whose certs are about to lapse. Read-only.","kind":"exec","risk":"low","side_effects":["One `rke2 certificate check` call.","Read-only."],"args":[],"examples":[{"title":"Certificate expiry","args":{}}],"search_terms":[],"command":{"binary":"rke2","argv":["certificate","check","--output","table"]}},{"id":"rke2.crictl_images","title":"List images on this node (crictl images)","summary":"List the container images present in this node's RKE2 containerd — repository, tag, image id, and size. Use to confirm an image is actually pulled on a node (ImagePullBackOff triage) or to see disk pressure from images. Read-only.","description":"List the container images present in this node's RKE2 containerd — repository, tag, image id, and size. Use to confirm an image is actually pulled on a node (ImagePullBackOff triage) or to see disk pressure from images. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl images call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"Node images","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl images"]}},{"id":"rke2.crictl_pods","title":"List pod sandboxes on this node (crictl pods)","summary":"List pod sandboxes on this node's RKE2 containerd — pod id, name, namespace, state, age. The CRI view of which pods the node actually has, independent of the API server. Read-only.","description":"List pod sandboxes on this node's RKE2 containerd — pod id, name, namespace, state, age. The CRI view of which pods the node actually has, independent of the API server. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl pods call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"Pod sandboxes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl pods"]}},{"id":"rke2.crictl_ps","title":"List containers on this node (crictl ps -a)","summary":"List all containers (running and stopped) on this node's RKE2 containerd — container id, image, state, name, attempt count, and pod. The CRI-level truth when kubelet/kubectl disagree about what's running on a node, and where you see crash/restart loops. Read-only.","description":"List all containers (running and stopped) on this node's RKE2 containerd — container id, image, state, name, attempt count, and pod. The CRI-level truth when kubelet/kubectl disagree about what's running on a node, and where you see crash/restart loops. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl ps call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl ps -a"]}},{"id":"rke2.etcd_health","title":"Check embedded etcd health (etcdctl endpoint health + status)","summary":"Check the embedded etcd's live health and status on this RKE2 server node — `etcdctl endpoint health` (is the member committing proposals?) followed by `endpoint status` (etcd version, DB size, leader, raft term/index).","description":"Check the embedded etcd's live health and status on this RKE2 server node — `etcdctl endpoint health` (is the member committing proposals?) followed by `endpoint status` (etcd version, DB size, leader, raft term/index). The direct read of etcd that snapshot-list and /readyz only approximate. RKE2 ships no etcdctl on the host PATH, so this runs the etcdctl already inside the running etcd static-pod container (found via crictl), authenticating to the local client endpoint (https://127.0.0.1:2379) with RKE2's own etcd server CA and the etcd server-client cert. Read-only; exits non-zero if etcd is unhealthy.","kind":"exec","risk":"low","side_effects":["One crictl exec into the running etcd container, running two etcdctl reads.","Read-only; no etcd writes, no snapshots, no member changes."],"args":[],"examples":[{"title":"Embedded etcd health and status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -e\nCR=/var/lib/rancher/rke2/bin/crictl\nCID=$(\"$CR\" ps --name etcd --state Running -q | head -n1)\n[ -n \"$CID\" ] || { echo \"no running etcd container on this node — is this an RKE2 server (etcd) node?\" >&2; exit 1; }\nTLS=/var/lib/rancher/rke2/server/tls/etcd\necho \"=== endpoint health ===\"\n\"$CR\" exec \"$CID\" etcdctl \\\n  --endpoints=https://127.0.0.1:2379 \\\n  --cacert=\"$TLS\"/server-ca.crt \\\n  --cert=\"$TLS\"/server-client.crt \\\n  --key=\"$TLS\"/server-client.key \\\n  --write-out=table endpoint health\necho \"=== endpoint status ===\"\n\"$CR\" exec \"$CID\" etcdctl \\\n  --endpoints=https://127.0.0.1:2379 \\\n  --cacert=\"$TLS\"/server-ca.crt \\\n  --cert=\"$TLS\"/server-client.crt \\\n  --key=\"$TLS\"/server-client.key \\\n  --write-out=table endpoint status\n"]}},{"id":"rke2.etcd_snapshot_list","title":"List etcd snapshots (rke2 etcd-snapshot ls)","summary":"List the embedded-etcd snapshots RKE2 has taken — name, location (local / S3), size, and creation time. Confirms backups are current; an empty or stale list is an etcd-recovery risk. Read-only.","description":"List the embedded-etcd snapshots RKE2 has taken — name, location (local / S3), size, and creation time. Confirms backups are current; an empty or stale list is an etcd-recovery risk. Read-only.","kind":"exec","risk":"low","side_effects":["One `rke2 etcd-snapshot list` call.","Read-only."],"args":[],"examples":[{"title":"List snapshots","args":{}}],"search_terms":[],"command":{"binary":"rke2","argv":["etcd-snapshot","ls"]}}],"previous_versions":[{"version":"0.2.2","content_hash":"sha256:05d0c67184f9fe379307b53eecd62dc0211bd3fc4f05a9cd36bc1e46166007b4","tarball_url":"https://registry.emisar.dev/v1/packs/rke2/0.2.2/05d0c67184f9fe379307b53eecd62dc0211bd3fc4f05a9cd36bc1e46166007b4/pack.tar.gz","actions":[{"id":"rke2.certificate_check","title":"Check RKE2 certificate expiry (rke2 certificate check)","summary":"Show per-certificate subject, status, and expiry date for this node's RKE2 certs. RKE2 leaf certs default to 365 days and auto-renew on restart within 90 days of expiry; this surfaces a node whose certs are about to lapse. Read-only.","description":"Show per-certificate subject, status, and expiry date for this node's RKE2 certs. RKE2 leaf certs default to 365 days and auto-renew on restart within 90 days of expiry; this surfaces a node whose certs are about to lapse. Read-only.","kind":"exec","risk":"low","side_effects":["One `rke2 certificate check` call.","Read-only."],"args":[],"examples":[{"title":"Certificate expiry","args":{}}],"search_terms":[],"command":{"binary":"rke2","argv":["certificate","check","--output","table"]}},{"id":"rke2.crictl_images","title":"List images on this node (crictl images)","summary":"List the container images present in this node's RKE2 containerd — repository, tag, image id, and size. Use to confirm an image is actually pulled on a node (ImagePullBackOff triage) or to see disk pressure from images. Read-only.","description":"List the container images present in this node's RKE2 containerd — repository, tag, image id, and size. Use to confirm an image is actually pulled on a node (ImagePullBackOff triage) or to see disk pressure from images. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl images call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"Node images","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl images"]}},{"id":"rke2.crictl_pods","title":"List pod sandboxes on this node (crictl pods)","summary":"List pod sandboxes on this node's RKE2 containerd — pod id, name, namespace, state, age. The CRI view of which pods the node actually has, independent of the API server. Read-only.","description":"List pod sandboxes on this node's RKE2 containerd — pod id, name, namespace, state, age. The CRI view of which pods the node actually has, independent of the API server. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl pods call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"Pod sandboxes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl pods"]}},{"id":"rke2.crictl_ps","title":"List containers on this node (crictl ps -a)","summary":"List all containers (running and stopped) on this node's RKE2 containerd — container id, image, state, name, attempt count, and pod. The CRI-level truth when kubelet/kubectl disagree about what's running on a node, and where you see crash/restart loops. Read-only.","description":"List all containers (running and stopped) on this node's RKE2 containerd — container id, image, state, name, attempt count, and pod. The CRI-level truth when kubelet/kubectl disagree about what's running on a node, and where you see crash/restart loops. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl ps call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl ps -a"]}},{"id":"rke2.etcd_health","title":"Check embedded etcd health (etcdctl endpoint health + status)","summary":"Check the embedded etcd's live health and status on this RKE2 server node — `etcdctl endpoint health` (is the member committing proposals?) followed by `endpoint status` (etcd version, DB size, leader, raft term/index).","description":"Check the embedded etcd's live health and status on this RKE2 server node — `etcdctl endpoint health` (is the member committing proposals?) followed by `endpoint status` (etcd version, DB size, leader, raft term/index). The direct read of etcd that snapshot-list and /readyz only approximate. RKE2 ships no etcdctl on the host PATH, so this runs the etcdctl already inside the running etcd static-pod container (found via crictl), authenticating to the local client endpoint (https://127.0.0.1:2379) with RKE2's own etcd server CA and the etcd server-client cert. Read-only; exits non-zero if etcd is unhealthy.","kind":"exec","risk":"low","side_effects":["One crictl exec into the running etcd container, running two etcdctl reads.","Read-only; no etcd writes, no snapshots, no member changes."],"args":[],"examples":[{"title":"Embedded etcd health and status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -e\nCR=/var/lib/rancher/rke2/bin/crictl\nCID=$(\"$CR\" ps --name etcd --state Running -q | head -n1)\n[ -n \"$CID\" ] || { echo \"no running etcd container on this node — is this an RKE2 server (etcd) node?\" >&2; exit 1; }\nTLS=/var/lib/rancher/rke2/server/tls/etcd\necho \"=== endpoint health ===\"\n\"$CR\" exec \"$CID\" etcdctl \\\n  --endpoints=https://127.0.0.1:2379 \\\n  --cacert=\"$TLS\"/server-ca.crt \\\n  --cert=\"$TLS\"/server-client.crt \\\n  --key=\"$TLS\"/server-client.key \\\n  --write-out=table endpoint health\necho \"=== endpoint status ===\"\n\"$CR\" exec \"$CID\" etcdctl \\\n  --endpoints=https://127.0.0.1:2379 \\\n  --cacert=\"$TLS\"/server-ca.crt \\\n  --cert=\"$TLS\"/server-client.crt \\\n  --key=\"$TLS\"/server-client.key \\\n  --write-out=table endpoint status\n"]}},{"id":"rke2.etcd_snapshot_list","title":"List etcd snapshots (rke2 etcd-snapshot ls)","summary":"List the embedded-etcd snapshots RKE2 has taken — name, location (local / S3), size, and creation time. Confirms backups are current; an empty or stale list is an etcd-recovery risk. Read-only.","description":"List the embedded-etcd snapshots RKE2 has taken — name, location (local / S3), size, and creation time. Confirms backups are current; an empty or stale list is an etcd-recovery risk. Read-only.","kind":"exec","risk":"low","side_effects":["One `rke2 etcd-snapshot list` call.","Read-only."],"args":[],"examples":[{"title":"List snapshots","args":{}}],"search_terms":[],"command":{"binary":"rke2","argv":["etcd-snapshot","ls"]}}]},{"version":"0.2.0","content_hash":"sha256:1809a6aea4df6f03697ee022e66473b67593e7d2329fe7f6baf3bc54cc683926","tarball_url":"https://registry.emisar.dev/v1/packs/rke2/0.2.0/1809a6aea4df6f03697ee022e66473b67593e7d2329fe7f6baf3bc54cc683926/pack.tar.gz","actions":[{"id":"rke2.certificate_check","title":"Check RKE2 certificate expiry (rke2 certificate check)","summary":"Show per-certificate subject, status, and expiry date for this node's RKE2 certs. RKE2 leaf certs default to 365 days and auto-renew on restart within 90 days of expiry; this surfaces a node whose certs are about to lapse. Read-only.","description":"Show per-certificate subject, status, and expiry date for this node's RKE2 certs. RKE2 leaf certs default to 365 days and auto-renew on restart within 90 days of expiry; this surfaces a node whose certs are about to lapse. Read-only.","kind":"exec","risk":"low","side_effects":["One `rke2 certificate check` call.","Read-only."],"args":[],"examples":[{"title":"Certificate expiry","args":{}}],"search_terms":[],"command":{"binary":"rke2","argv":["certificate","check","--output","table"]}},{"id":"rke2.crictl_images","title":"List images on this node (crictl images)","summary":"List the container images present in this node's RKE2 containerd — repository, tag, image id, and size. Use to confirm an image is actually pulled on a node (ImagePullBackOff triage) or to see disk pressure from images. Read-only.","description":"List the container images present in this node's RKE2 containerd — repository, tag, image id, and size. Use to confirm an image is actually pulled on a node (ImagePullBackOff triage) or to see disk pressure from images. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl images call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"Node images","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl images"]}},{"id":"rke2.crictl_pods","title":"List pod sandboxes on this node (crictl pods)","summary":"List pod sandboxes on this node's RKE2 containerd — pod id, name, namespace, state, age. The CRI view of which pods the node actually has, independent of the API server. Read-only.","description":"List pod sandboxes on this node's RKE2 containerd — pod id, name, namespace, state, age. The CRI view of which pods the node actually has, independent of the API server. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl pods call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"Pod sandboxes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl pods"]}},{"id":"rke2.crictl_ps","title":"List containers on this node (crictl ps -a)","summary":"List all containers (running and stopped) on this node's RKE2 containerd — container id, image, state, name, attempt count, and pod. The CRI-level truth when kubelet/kubectl disagree about what's running on a node, and where you see crash/restart loops. Read-only.","description":"List all containers (running and stopped) on this node's RKE2 containerd — container id, image, state, name, attempt count, and pod. The CRI-level truth when kubelet/kubectl disagree about what's running on a node, and where you see crash/restart loops. Read-only.","kind":"exec","risk":"low","side_effects":["One crictl ps call against the node container runtime.","Read-only."],"args":[],"examples":[{"title":"All containers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","/var/lib/rancher/rke2/bin/crictl ps -a"]}},{"id":"rke2.etcd_health","title":"Check embedded etcd health (etcdctl endpoint health + status)","summary":"Check the embedded etcd's live health and status on this RKE2 server node — `etcdctl endpoint health` (is the member committing proposals?) followed by `endpoint status` (etcd version, DB size, leader, raft term/index).","description":"Check the embedded etcd's live health and status on this RKE2 server node — `etcdctl endpoint health` (is the member committing proposals?) followed by `endpoint status` (etcd version, DB size, leader, raft term/index). The direct read of etcd that snapshot-list and /readyz only approximate. RKE2 ships no etcdctl on the host PATH, so this runs the etcdctl already inside the running etcd static-pod container (found via crictl), authenticating to the local client endpoint (https://127.0.0.1:2379) with RKE2's own etcd server CA and the etcd server-client cert. Read-only; exits non-zero if etcd is unhealthy.","kind":"exec","risk":"low","side_effects":["One crictl exec into the running etcd container, running two etcdctl reads.","Read-only; no etcd writes, no snapshots, no member changes."],"args":[],"examples":[{"title":"Embedded etcd health and status","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","set -e\nCR=/var/lib/rancher/rke2/bin/crictl\nCID=$(\"$CR\" ps --name etcd --state Running -q | head -n1)\n[ -n \"$CID\" ] || { echo \"no running etcd container on this node — is this an RKE2 server (etcd) node?\" >&2; exit 1; }\nTLS=/var/lib/rancher/rke2/server/tls/etcd\necho \"=== endpoint health ===\"\n\"$CR\" exec \"$CID\" etcdctl \\\n  --endpoints=https://127.0.0.1:2379 \\\n  --cacert=\"$TLS\"/server-ca.crt \\\n  --cert=\"$TLS\"/server-client.crt \\\n  --key=\"$TLS\"/server-client.key \\\n  --write-out=table endpoint health\necho \"=== endpoint status ===\"\n\"$CR\" exec \"$CID\" etcdctl \\\n  --endpoints=https://127.0.0.1:2379 \\\n  --cacert=\"$TLS\"/server-ca.crt \\\n  --cert=\"$TLS\"/server-client.crt \\\n  --key=\"$TLS\"/server-client.key \\\n  --write-out=table endpoint status\n"]}},{"id":"rke2.etcd_snapshot_list","title":"List etcd snapshots (rke2 etcd-snapshot ls)","summary":"List the embedded-etcd snapshots RKE2 has taken — name, location (local / S3), size, and creation time. Confirms backups are current; an empty or stale list is an etcd-recovery risk. Read-only.","description":"List the embedded-etcd snapshots RKE2 has taken — name, location (local / S3), size, and creation time. Confirms backups are current; an empty or stale list is an etcd-recovery risk. Read-only.","kind":"exec","risk":"low","side_effects":["One `rke2 etcd-snapshot list` call.","Read-only."],"args":[],"examples":[{"title":"List snapshots","args":{}}],"search_terms":[],"command":{"binary":"rke2","argv":["etcd-snapshot","ls"]}}]}]},{"id":"sentry","name":"Sentry error monitoring","version":"0.1.5","description":"Governed Sentry issue triage, release, ingest-key, volume-stats, and alert-rule operations against sentry.io or a self-hosted instance. Auth via SENTRY_AUTH_TOKEN on the runner host.","vendor":"emisar","homepage":"https://emisar.dev/packs/sentry","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/sentry","content_hash":"sha256:877743f5c02c05480a1d594b27c9b5cb2207545f4028a9eb8efb698688288412","tarball_url":"https://registry.emisar.dev/v1/packs/sentry/0.1.5/877743f5c02c05480a1d594b27c9b5cb2207545f4028a9eb8efb698688288412/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Calls the Sentry Web API under `$SENTRY_URL`/api/0 with curl. The token is sent as an Authorization Bearer header over curl stdin and is never placed in argv or action output. Allowlist both variables in the runner's `execution.inherit_env` configuration.","env":[{"name":"SENTRY_URL","description":"Base URL of the Sentry instance (scheme + host, no trailing path). Defaults to cloud sentry.io; set your region URL or the self-hosted base instead.","default":"https://sentry.io","example":"https://sentry.example.com"},{"name":"SENTRY_AUTH_TOKEN","required":true,"description":"Organization auth token or internal integration token. Scope it to the org/projects and permissions the actions you enable need."}],"notes":["Mint the token in Sentry under Settings → Auth Tokens for an organization token, or Settings → Developer Settings → Custom Integrations for an internal integration. A personal token can be created straight from [sentry.io/settings/account/api/auth-tokens](https://sentry.io/settings/account/api/auth-tokens/new-token/); the organization page needs your org slug, so it has no generic link.","Organization and project arguments are slugs — sentry.list_organizations and sentry.list_projects return them for use in the other actions.","Token scopes by family: org:read + project:read for the listings; event:read for issues, events, and tags; event:write for resolve/ignore/assign; project:write for ingest-key enable/disable; org:read for stats; alerts:read for alert rules.","List actions return one bounded page plus pagination.next_cursor parsed from Sentry's Link header; pass it back as the cursor argument for the next page.","Works against cloud sentry.io (including region URLs) and self-hosted Sentry; the API paths used here have been stable across both for years.","Sending events, project/team administration, member management, and API token management are separate trust surfaces this pack does not touch."],"verify":"sentry.list_organizations"},"actions":[{"id":"sentry.assign_issue","title":"Assign issue","summary":"Assign one Sentry issue to a user or team; the assignee is notified per their settings, and a wrong assignment misroutes the triage.","description":"Assign one Sentry issue to a user or team; the assignee is notified per their settings, and a wrong assignment misroutes the triage.","kind":"script","risk":"medium","side_effects":["The issue shows as owned by the assignee and their notifications apply.","Fully reversible by reassigning."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"assignee","type":"string","required":true,"description":"Actor to assign — a username, email, user ID, or team:slug.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9@._:-]{0,127}$","max_length":128}}],"examples":[{"title":"Route to the backend team","args":{"assignee":"team:backend","issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.disable_project_key","title":"Disable project ingest key","summary":"Disable one project client key (DSN); every client using it stops reporting immediately and those events are lost, so the project goes dark for that key until it is re-enabled.","description":"Disable one project client key (DSN); every client using it stops reporting immediately and those events are lost, so the project goes dark for that key until it is re-enabled.","kind":"script","risk":"high","side_effects":["Events sent with the key are rejected and not recoverable.","Alerting driven by those events goes quiet — absence of errors no longer means health."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"key_id","type":"string","required":true,"description":"Client key ID (sentry.list_project_keys returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Stop a runaway client","args":{"key_id":"cec9dfceb0b74c1c9a5e3c135585f364","organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.enable_project_key","title":"Enable project ingest key","summary":"Re-enable one disabled project client key (DSN); clients using it resume reporting immediately.","description":"Re-enable one disabled project client key (DSN); clients using it resume reporting immediately.","kind":"script","risk":"medium","side_effects":["Events sent with the key are accepted again."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"key_id","type":"string","required":true,"description":"Client key ID (sentry.list_project_keys returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Restore ingest","args":{"key_id":"cec9dfceb0b74c1c9a5e3c135585f364","organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.issue_details","title":"Show issue details","summary":"Show one Sentry issue's status, assignee, first/last seen, event and user counts, and metadata.","description":"Show one Sentry issue's status, assignee, first/last seen, event and user counts, and metadata.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID (sentry.list_issues returns it).","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Issue","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.issue_latest_event","title":"Show latest issue event","summary":"Show an issue's most recent event with stacktrace, breadcrumbs, and request context. The payload is arbitrary application data — whatever the app put in messages, breadcrumbs, and headers — and Sentry's server-side scrubbing is best-effort, so treat it as sensitive diagnostics.","description":"Show an issue's most recent event with stacktrace, breadcrumbs, and request context. The payload is arbitrary application data — whatever the app put in messages, breadcrumbs, and headers — and Sentry's server-side scrubbing is best-effort, so treat it as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Latest stacktrace","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.issue_tags","title":"Show issue tags","summary":"Show an issue's tag distribution — which releases, environments, browsers, or servers the error hits most.","description":"Show an issue's tag distribution — which releases, environments, browsers, or servers the error hits most.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Tag breakdown","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.list_alert_rules","title":"List issue alert rules","summary":"List a project's issue alert rules — conditions, actions, and frequency — to see what pages whom and why.","description":"List a project's issue alert rules — conditions, actions, and frequency — to see what pages whom and why.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}}],"examples":[{"title":"Alert rules","args":{"organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.list_issues","title":"List issues","summary":"List one bounded page of a project's Sentry issues — title, culprit, event and user counts, status — filtered by a search query and sorted by date, frequency, first-seen, or affected users.","description":"List one bounded page of a project's Sentry issues — title, culprit, event and user counts, status — filtered by a search query and sorted by date, frequency, first-seen, or affected users.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"query","type":"string","required":false,"default":"is:unresolved","description":"Sentry issue search query, e.g. \"is:unresolved release:2.1.0\".","validation":{"pattern":"^[ -~]*$","max_length":400}},{"name":"stats_period","type":"string","required":false,"default":"24h","description":"Window for the event-count stats on each issue.","validation":{"enum":["24h","14d"]}},{"name":"sort","type":"string","required":false,"default":"date","description":"Sort order — last seen, first seen, event frequency, or affected users.","validation":{"enum":["date","new","freq","user"]}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Issues returned in this page.","validation":{"min":1,"max":100}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Most frequent unresolved errors","args":{"organization":"acme","project":"backend","sort":"freq"}}],"search_terms":[]},{"id":"sentry.list_organizations","title":"List organizations","summary":"List one bounded page of Sentry organizations the token can read — the org slugs the other actions need.","description":"List one bounded page of Sentry organizations the token can read — the org slugs the other actions need.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Organizations","args":{}}],"search_terms":[]},{"id":"sentry.list_project_keys","title":"List project ingest keys","summary":"List a project's client keys (DSNs) with their active state and rate limits. Sentry's key space is vendor-owned, and the legacy secret-DSN fields are removed before output leaves the runner; the public DSN remains, which is enough for a client to send events.","description":"List a project's client keys (DSNs) with their active state and rate limits. Sentry's key space is vendor-owned, and the legacy secret-DSN fields are removed before output leaves the runner; the public DSN remains, which is enough for a client to send events.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}}],"examples":[{"title":"Keys","args":{"organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.list_projects","title":"List projects","summary":"List one bounded page of an organization's Sentry projects with slugs, platforms, and status.","description":"List one bounded page of an organization's Sentry projects with slugs, platforms, and status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Projects","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.list_releases","title":"List releases","summary":"List one bounded page of an organization's releases with versions, dates, and new-issue counts — for checking whether an error spike lines up with a deploy.","description":"List one bounded page of an organization's releases with versions, dates, and new-issue counts — for checking whether an error spike lines up with a deploy.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Recent releases","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.org_stats","title":"Show organization event stats","summary":"Show an organization's ingested event volume grouped by category and outcome (accepted, rate limited, filtered, dropped) — for quota debugging and spotting ingest floods.","description":"Show an organization's ingested event volume grouped by category and outcome (accepted, rate limited, filtered, dropped) — for quota debugging and spotting ingest floods.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"stats_period","type":"string","required":false,"default":"24h","description":"How far back to report.","validation":{"enum":["1h","24h","7d","14d","30d","90d"]}},{"name":"interval","type":"string","required":false,"default":"1h","description":"Bucket size for the series.","validation":{"enum":["5m","1h","1d"]}}],"examples":[{"title":"Last 24h by outcome","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.set_issue_status","title":"Set issue status","summary":"Resolve, unresolve, or ignore one Sentry issue; ignoring silences its alerts (optionally for a bounded number of minutes), and resolving re-alerts as a regression if the error returns.","description":"Resolve, unresolve, or ignore one Sentry issue; ignoring silences its alerts (optionally for a bounded number of minutes), and resolving re-alerts as a regression if the error returns.","kind":"script","risk":"medium","side_effects":["Alert rules stop or resume firing for the issue according to the new status.","Fully reversible by setting the status back."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"status","type":"string","required":true,"description":"Status to apply.","validation":{"enum":["resolved","unresolved","ignored"]}},{"name":"ignore_minutes","type":"integer","required":false,"default":0,"description":"When ignoring, silence for this many minutes; 0 ignores until the status changes. Ignored for other statuses.","validation":{"min":0,"max":43200}}],"examples":[{"title":"Resolve","args":{"issue_id":"1234567890","organization":"acme","status":"resolved"}},{"title":"Snooze for an hour","args":{"ignore_minutes":60,"issue_id":"1234567890","organization":"acme","status":"ignored"}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.4","content_hash":"sha256:5a01db439d2d779f117ef296963029671a5d456e042b1e5749ba80c47b317b52","tarball_url":"https://registry.emisar.dev/v1/packs/sentry/0.1.4/5a01db439d2d779f117ef296963029671a5d456e042b1e5749ba80c47b317b52/pack.tar.gz","actions":[{"id":"sentry.assign_issue","title":"Assign issue","summary":"Assign one Sentry issue to a user or team; the assignee is notified per their settings, and a wrong assignment misroutes the triage.","description":"Assign one Sentry issue to a user or team; the assignee is notified per their settings, and a wrong assignment misroutes the triage.","kind":"script","risk":"medium","side_effects":["The issue shows as owned by the assignee and their notifications apply.","Fully reversible by reassigning."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"assignee","type":"string","required":true,"description":"Actor to assign — a username, email, user ID, or team:slug.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9@._:-]{0,127}$","max_length":128}}],"examples":[{"title":"Route to the backend team","args":{"assignee":"team:backend","issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.disable_project_key","title":"Disable project ingest key","summary":"Disable one project client key (DSN); every client using it stops reporting immediately and those events are lost, so the project goes dark for that key until it is re-enabled.","description":"Disable one project client key (DSN); every client using it stops reporting immediately and those events are lost, so the project goes dark for that key until it is re-enabled.","kind":"script","risk":"high","side_effects":["Events sent with the key are rejected and not recoverable.","Alerting driven by those events goes quiet — absence of errors no longer means health."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"key_id","type":"string","required":true,"description":"Client key ID (sentry.list_project_keys returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Stop a runaway client","args":{"key_id":"cec9dfceb0b74c1c9a5e3c135585f364","organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.enable_project_key","title":"Enable project ingest key","summary":"Re-enable one disabled project client key (DSN); clients using it resume reporting immediately.","description":"Re-enable one disabled project client key (DSN); clients using it resume reporting immediately.","kind":"script","risk":"medium","side_effects":["Events sent with the key are accepted again."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"key_id","type":"string","required":true,"description":"Client key ID (sentry.list_project_keys returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Restore ingest","args":{"key_id":"cec9dfceb0b74c1c9a5e3c135585f364","organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.issue_details","title":"Show issue details","summary":"Show one Sentry issue's status, assignee, first/last seen, event and user counts, and metadata.","description":"Show one Sentry issue's status, assignee, first/last seen, event and user counts, and metadata.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID (sentry.list_issues returns it).","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Issue","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.issue_latest_event","title":"Show latest issue event","summary":"Show an issue's most recent event with stacktrace, breadcrumbs, and request context. The payload is arbitrary application data — whatever the app put in messages, breadcrumbs, and headers — and Sentry's server-side scrubbing is best-effort, so treat it as sensitive diagnostics.","description":"Show an issue's most recent event with stacktrace, breadcrumbs, and request context. The payload is arbitrary application data — whatever the app put in messages, breadcrumbs, and headers — and Sentry's server-side scrubbing is best-effort, so treat it as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Latest stacktrace","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.issue_tags","title":"Show issue tags","summary":"Show an issue's tag distribution — which releases, environments, browsers, or servers the error hits most.","description":"Show an issue's tag distribution — which releases, environments, browsers, or servers the error hits most.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Tag breakdown","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.list_alert_rules","title":"List issue alert rules","summary":"List a project's issue alert rules — conditions, actions, and frequency — to see what pages whom and why.","description":"List a project's issue alert rules — conditions, actions, and frequency — to see what pages whom and why.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}}],"examples":[{"title":"Alert rules","args":{"organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.list_issues","title":"List issues","summary":"List one bounded page of a project's Sentry issues — title, culprit, event and user counts, status — filtered by a search query and sorted by date, frequency, first-seen, or affected users.","description":"List one bounded page of a project's Sentry issues — title, culprit, event and user counts, status — filtered by a search query and sorted by date, frequency, first-seen, or affected users.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"query","type":"string","required":false,"default":"is:unresolved","description":"Sentry issue search query, e.g. \"is:unresolved release:2.1.0\".","validation":{"pattern":"^[ -~]*$","max_length":400}},{"name":"stats_period","type":"string","required":false,"default":"24h","description":"Window for the event-count stats on each issue.","validation":{"enum":["24h","14d"]}},{"name":"sort","type":"string","required":false,"default":"date","description":"Sort order — last seen, first seen, event frequency, or affected users.","validation":{"enum":["date","new","freq","user"]}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Issues returned in this page.","validation":{"min":1,"max":100}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Most frequent unresolved errors","args":{"organization":"acme","project":"backend","sort":"freq"}}],"search_terms":[]},{"id":"sentry.list_organizations","title":"List organizations","summary":"List one bounded page of Sentry organizations the token can read — the org slugs the other actions need.","description":"List one bounded page of Sentry organizations the token can read — the org slugs the other actions need.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Organizations","args":{}}],"search_terms":[]},{"id":"sentry.list_project_keys","title":"List project ingest keys","summary":"List a project's client keys (DSNs) with their active state and rate limits. Sentry's key space is vendor-owned, and the legacy secret-DSN fields are removed before output leaves the runner; the public DSN remains, which is enough for a client to send events.","description":"List a project's client keys (DSNs) with their active state and rate limits. Sentry's key space is vendor-owned, and the legacy secret-DSN fields are removed before output leaves the runner; the public DSN remains, which is enough for a client to send events.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}}],"examples":[{"title":"Keys","args":{"organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.list_projects","title":"List projects","summary":"List one bounded page of an organization's Sentry projects with slugs, platforms, and status.","description":"List one bounded page of an organization's Sentry projects with slugs, platforms, and status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Projects","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.list_releases","title":"List releases","summary":"List one bounded page of an organization's releases with versions, dates, and new-issue counts — for checking whether an error spike lines up with a deploy.","description":"List one bounded page of an organization's releases with versions, dates, and new-issue counts — for checking whether an error spike lines up with a deploy.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Recent releases","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.org_stats","title":"Show organization event stats","summary":"Show an organization's ingested event volume grouped by category and outcome (accepted, rate limited, filtered, dropped) — for quota debugging and spotting ingest floods.","description":"Show an organization's ingested event volume grouped by category and outcome (accepted, rate limited, filtered, dropped) — for quota debugging and spotting ingest floods.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"stats_period","type":"string","required":false,"default":"24h","description":"How far back to report.","validation":{"enum":["1h","24h","7d","14d","30d","90d"]}},{"name":"interval","type":"string","required":false,"default":"1h","description":"Bucket size for the series.","validation":{"enum":["5m","1h","1d"]}}],"examples":[{"title":"Last 24h by outcome","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.set_issue_status","title":"Set issue status","summary":"Resolve, unresolve, or ignore one Sentry issue; ignoring silences its alerts (optionally for a bounded number of minutes), and resolving re-alerts as a regression if the error returns.","description":"Resolve, unresolve, or ignore one Sentry issue; ignoring silences its alerts (optionally for a bounded number of minutes), and resolving re-alerts as a regression if the error returns.","kind":"script","risk":"medium","side_effects":["Alert rules stop or resume firing for the issue according to the new status.","Fully reversible by setting the status back."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"status","type":"string","required":true,"description":"Status to apply.","validation":{"enum":["resolved","unresolved","ignored"]}},{"name":"ignore_minutes","type":"integer","required":false,"default":0,"description":"When ignoring, silence for this many minutes; 0 ignores until the status changes. Ignored for other statuses.","validation":{"min":0,"max":43200}}],"examples":[{"title":"Resolve","args":{"issue_id":"1234567890","organization":"acme","status":"resolved"}},{"title":"Snooze for an hour","args":{"ignore_minutes":60,"issue_id":"1234567890","organization":"acme","status":"ignored"}}],"search_terms":[]}]},{"version":"0.1.0","content_hash":"sha256:8a33af4a63e08318ed0aad6afefbd3f5a1c84f9636e7a0de1f6a1ad902ef18ee","tarball_url":"https://registry.emisar.dev/v1/packs/sentry/0.1.0/8a33af4a63e08318ed0aad6afefbd3f5a1c84f9636e7a0de1f6a1ad902ef18ee/pack.tar.gz","actions":[{"id":"sentry.assign_issue","title":"Assign issue","summary":"Assign one Sentry issue to a user or team; the assignee is notified per their settings, and a wrong assignment misroutes the triage.","description":"Assign one Sentry issue to a user or team; the assignee is notified per their settings, and a wrong assignment misroutes the triage.","kind":"script","risk":"medium","side_effects":["The issue shows as owned by the assignee and their notifications apply.","Fully reversible by reassigning."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"assignee","type":"string","required":true,"description":"Actor to assign — a username, email, user ID, or team:slug.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9@._:-]{0,127}$","max_length":128}}],"examples":[{"title":"Route to the backend team","args":{"assignee":"team:backend","issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.disable_project_key","title":"Disable project ingest key","summary":"Disable one project client key (DSN); every client using it stops reporting immediately and those events are lost, so the project goes dark for that key until it is re-enabled.","description":"Disable one project client key (DSN); every client using it stops reporting immediately and those events are lost, so the project goes dark for that key until it is re-enabled.","kind":"script","risk":"high","side_effects":["Events sent with the key are rejected and not recoverable.","Alerting driven by those events goes quiet — absence of errors no longer means health."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"key_id","type":"string","required":true,"description":"Client key ID (sentry.list_project_keys returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Stop a runaway client","args":{"key_id":"cec9dfceb0b74c1c9a5e3c135585f364","organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.enable_project_key","title":"Enable project ingest key","summary":"Re-enable one disabled project client key (DSN); clients using it resume reporting immediately.","description":"Re-enable one disabled project client key (DSN); clients using it resume reporting immediately.","kind":"script","risk":"medium","side_effects":["Events sent with the key are accepted again."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"key_id","type":"string","required":true,"description":"Client key ID (sentry.list_project_keys returns it).","validation":{"pattern":"^[a-f0-9]{32}$"}}],"examples":[{"title":"Restore ingest","args":{"key_id":"cec9dfceb0b74c1c9a5e3c135585f364","organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.issue_details","title":"Show issue details","summary":"Show one Sentry issue's status, assignee, first/last seen, event and user counts, and metadata.","description":"Show one Sentry issue's status, assignee, first/last seen, event and user counts, and metadata.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID (sentry.list_issues returns it).","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Issue","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.issue_latest_event","title":"Show latest issue event","summary":"Show an issue's most recent event with stacktrace, breadcrumbs, and request context. The payload is arbitrary application data — whatever the app put in messages, breadcrumbs, and headers — and Sentry's server-side scrubbing is best-effort, so treat it as sensitive diagnostics.","description":"Show an issue's most recent event with stacktrace, breadcrumbs, and request context. The payload is arbitrary application data — whatever the app put in messages, breadcrumbs, and headers — and Sentry's server-side scrubbing is best-effort, so treat it as sensitive diagnostics.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Latest stacktrace","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.issue_tags","title":"Show issue tags","summary":"Show an issue's tag distribution — which releases, environments, browsers, or servers the error hits most.","description":"Show an issue's tag distribution — which releases, environments, browsers, or servers the error hits most.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}}],"examples":[{"title":"Tag breakdown","args":{"issue_id":"1234567890","organization":"acme"}}],"search_terms":[]},{"id":"sentry.list_alert_rules","title":"List issue alert rules","summary":"List a project's issue alert rules — conditions, actions, and frequency — to see what pages whom and why.","description":"List a project's issue alert rules — conditions, actions, and frequency — to see what pages whom and why.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}}],"examples":[{"title":"Alert rules","args":{"organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.list_issues","title":"List issues","summary":"List one bounded page of a project's Sentry issues — title, culprit, event and user counts, status — filtered by a search query and sorted by date, frequency, first-seen, or affected users.","description":"List one bounded page of a project's Sentry issues — title, culprit, event and user counts, status — filtered by a search query and sorted by date, frequency, first-seen, or affected users.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"query","type":"string","required":false,"default":"is:unresolved","description":"Sentry issue search query, e.g. \"is:unresolved release:2.1.0\".","validation":{"pattern":"^[ -~]*$","max_length":400}},{"name":"stats_period","type":"string","required":false,"default":"24h","description":"Window for the event-count stats on each issue.","validation":{"enum":["24h","14d"]}},{"name":"sort","type":"string","required":false,"default":"date","description":"Sort order — last seen, first seen, event frequency, or affected users.","validation":{"enum":["date","new","freq","user"]}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Issues returned in this page.","validation":{"min":1,"max":100}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Most frequent unresolved errors","args":{"organization":"acme","project":"backend","sort":"freq"}}],"search_terms":[]},{"id":"sentry.list_organizations","title":"List organizations","summary":"List one bounded page of Sentry organizations the token can read — the org slugs the other actions need.","description":"List one bounded page of Sentry organizations the token can read — the org slugs the other actions need.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Organizations","args":{}}],"search_terms":[]},{"id":"sentry.list_project_keys","title":"List project ingest keys","summary":"List a project's client keys (DSNs) with their active state and rate limits. Sentry's key space is vendor-owned, and the legacy secret-DSN fields are removed before output leaves the runner; the public DSN remains, which is enough for a client to send events.","description":"List a project's client keys (DSNs) with their active state and rate limits. Sentry's key space is vendor-owned, and the legacy secret-DSN fields are removed before output leaves the runner; the public DSN remains, which is enough for a client to send events.","kind":"script","risk":"medium","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"project","type":"string","required":true,"description":"Project slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}}],"examples":[{"title":"Keys","args":{"organization":"acme","project":"backend"}}],"search_terms":[]},{"id":"sentry.list_projects","title":"List projects","summary":"List one bounded page of an organization's Sentry projects with slugs, platforms, and status.","description":"List one bounded page of an organization's Sentry projects with slugs, platforms, and status.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Projects","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.list_releases","title":"List releases","summary":"List one bounded page of an organization's releases with versions, dates, and new-issue counts — for checking whether an error spike lines up with a deploy.","description":"List one bounded page of an organization's releases with versions, dates, and new-issue counts — for checking whether an error spike lines up with a deploy.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"cursor","type":"string","required":false,"default":"","description":"Continuation cursor from a previous page's pagination.next_cursor.","validation":{"pattern":"^[0-9A-Za-z:_=-]{0,120}$","max_length":120}}],"examples":[{"title":"Recent releases","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.org_stats","title":"Show organization event stats","summary":"Show an organization's ingested event volume grouped by category and outcome (accepted, rate limited, filtered, dropped) — for quota debugging and spotting ingest floods.","description":"Show an organization's ingested event volume grouped by category and outcome (accepted, rate limited, filtered, dropped) — for quota debugging and spotting ingest floods.","kind":"script","risk":"low","side_effects":["One read-only API request."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"stats_period","type":"string","required":false,"default":"24h","description":"How far back to report.","validation":{"enum":["1h","24h","7d","14d","30d","90d"]}},{"name":"interval","type":"string","required":false,"default":"1h","description":"Bucket size for the series.","validation":{"enum":["5m","1h","1d"]}}],"examples":[{"title":"Last 24h by outcome","args":{"organization":"acme"}}],"search_terms":[]},{"id":"sentry.set_issue_status","title":"Set issue status","summary":"Resolve, unresolve, or ignore one Sentry issue; ignoring silences its alerts (optionally for a bounded number of minutes), and resolving re-alerts as a regression if the error returns.","description":"Resolve, unresolve, or ignore one Sentry issue; ignoring silences its alerts (optionally for a bounded number of minutes), and resolving re-alerts as a regression if the error returns.","kind":"script","risk":"medium","side_effects":["Alert rules stop or resume firing for the issue according to the new status.","Fully reversible by setting the status back."],"args":[{"name":"organization","type":"string","required":true,"description":"Organization slug.","validation":{"pattern":"^[a-z0-9][a-z0-9._-]{0,63}$","max_length":64}},{"name":"issue_id","type":"string","required":true,"description":"Numeric issue ID.","validation":{"pattern":"^[0-9]{1,20}$"}},{"name":"status","type":"string","required":true,"description":"Status to apply.","validation":{"enum":["resolved","unresolved","ignored"]}},{"name":"ignore_minutes","type":"integer","required":false,"default":0,"description":"When ignoring, silence for this many minutes; 0 ignores until the status changes. Ignored for other statuses.","validation":{"min":0,"max":43200}}],"examples":[{"title":"Resolve","args":{"issue_id":"1234567890","organization":"acme","status":"resolved"}},{"title":"Snooze for an hour","args":{"ignore_minutes":60,"issue_id":"1234567890","organization":"acme","status":"ignored"}}],"search_terms":[]}]}]},{"id":"shell","name":"Arbitrary shell (staging break-glass)","version":"0.2.1","description":"STAGING-ONLY BREAK-GLASS. Runs an arbitrary operator-supplied shell script on the runner host via `/bin/sh -c`. This is the one capability emisar is built to avoid: it bypasses the declared-action model entirely — whatever the script says, runs, as the runner's user. It exists so an agent can verify a fix interactively on a staging host before that fix is encoded as a proper declared action or runbook. DO NOT install this pack on production runners and DO NOT enable it in production. Its single action is critical-risk, so the default policy denies it until an operator deliberately opts in; every run is fully audited.","vendor":"emisar","homepage":"https://emisar.dev/packs/shell","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/shell","content_hash":"sha256:778bc3f24a08887c64b05ccf819674b8baae2f210da855dc51fa722b9fb4c34c","tarball_url":"https://registry.emisar.dev/v1/packs/shell/0.2.1/778bc3f24a08887c64b05ccf819674b8baae2f210da855dc51fa722b9fb4c34c/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host via /bin/sh — no credentials needed. Intended ONLY for staging runners used to verify fixes before they are encoded as declared actions.","notes":["STAGING ONLY. Do not install on production runners; do not enable in production.","Runs as the runner's service user — keep that user least-privileged. The script can do anything that user can.","The single action is critical-risk: the default cloud policy DENIES critical, so it cannot run until an operator adds a rule. Keep it at require_approval (e.g. a shell.run_script override) so every run is human-gated.","Every invocation records the full script text in the local journal and the cloud audit log."]},"actions":[{"id":"shell.run_script","title":"Run a shell script (/bin/sh -c)","summary":"STAGING BREAK-GLASS — run an arbitrary shell script on the runner host via `/bin/sh -c`.","description":"STAGING BREAK-GLASS — run an arbitrary shell script on the runner host via `/bin/sh -c`. Bypasses the declared-action model: whatever you pass runs verbatim, as the runner's user, with no per-argument schema and no allow/deny bounds beyond the timeout and output caps. Use this ONLY on a staging host to verify a fix before encoding it as a proper declared action or runbook — never as a substitute for one, and never in production. Keep scripts short and reviewable; the full text is recorded in the audit log.","kind":"exec","risk":"critical","side_effects":["Executes arbitrary shell on the runner host as the runner's service user.","Can read, change, or destroy anything that user can reach — no schema, no allow/deny bounds.","Full script text is journaled locally and in the cloud audit log."],"args":[{"name":"script","type":"string","required":true,"description":"Shell script passed to `/bin/sh -c` as a single program. Prefer a few reviewable lines — this verifies a fix, it is not a deploy tool.","validation":{"max_length":5459}}],"examples":[{"title":"Verify a service recovered after a fix","args":{"script":"systemctl is-active nginx && curl -fsS http://localhost/health"}},{"title":"Inspect why a unit failed","args":{"script":"journalctl -u myapp -n 50 --no-pager | tail -20"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{{ args.script }}"]}}],"previous_versions":[{"version":"0.2.0","content_hash":"sha256:9a007c6f63cb23b776a4ced833ec531c70c547d8cceb653b6db9409fa9b581de","tarball_url":"https://registry.emisar.dev/v1/packs/shell/0.2.0/9a007c6f63cb23b776a4ced833ec531c70c547d8cceb653b6db9409fa9b581de/pack.tar.gz","actions":[{"id":"shell.run_script","title":"Run a shell script (/bin/sh -c)","summary":"STAGING BREAK-GLASS — run an arbitrary shell script on the runner host via `/bin/sh -c`.","description":"STAGING BREAK-GLASS — run an arbitrary shell script on the runner host via `/bin/sh -c`. Bypasses the declared-action model: whatever you pass runs verbatim, as the runner's user, with no per-argument schema and no allow/deny bounds beyond the timeout and output caps. Use this ONLY on a staging host to verify a fix before encoding it as a proper declared action or runbook — never as a substitute for one, and never in production. Keep scripts short and reviewable; the full text is recorded in the audit log.","kind":"exec","risk":"critical","side_effects":["Executes arbitrary shell on the runner host as the runner's service user.","Can read, change, or destroy anything that user can reach — no schema, no allow/deny bounds.","Full script text is journaled locally and in the cloud audit log."],"args":[{"name":"script","type":"string","required":true,"description":"Shell script passed to `/bin/sh -c` as a single program. Prefer a few reviewable lines — this verifies a fix, it is not a deploy tool.","validation":{"max_length":5459}}],"examples":[{"title":"Verify a service recovered after a fix","args":{"script":"systemctl is-active nginx && curl -fsS http://localhost/health"}},{"title":"Inspect why a unit failed","args":{"script":"journalctl -u myapp -n 50 --no-pager | tail -20"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{{ args.script }}"]}}]},{"version":"0.1.0","content_hash":"sha256:0884946aa3c313b3990a3539400d1cd2fb50051fc0efa717be738f6038593134","tarball_url":"https://registry.emisar.dev/v1/packs/shell/0.1.0/0884946aa3c313b3990a3539400d1cd2fb50051fc0efa717be738f6038593134/pack.tar.gz","actions":[{"id":"shell.run_script","title":"Run a shell script (/bin/sh -c)","summary":"STAGING BREAK-GLASS — run an arbitrary shell script on the runner host via `/bin/sh -c`.","description":"STAGING BREAK-GLASS — run an arbitrary shell script on the runner host via `/bin/sh -c`. Bypasses the declared-action model: whatever you pass runs verbatim, as the runner's user, with no per-argument schema and no allow/deny bounds beyond the timeout and output caps. Use this ONLY on a staging host to verify a fix before encoding it as a proper declared action or runbook — never as a substitute for one, and never in production. Keep scripts short and reviewable; the full text is recorded in the audit log.","kind":"exec","risk":"critical","side_effects":["Executes arbitrary shell on the runner host as the runner's service user.","Can read, change, or destroy anything that user can reach — no schema, no allow/deny bounds.","Full script text is journaled locally and in the cloud audit log."],"args":[{"name":"script","type":"string","required":true,"description":"Shell script passed to `/bin/sh -c` as a single program. Prefer a few reviewable lines — this verifies a fix, it is not a deploy tool.","validation":{"max_length":65536}}],"examples":[{"title":"Verify a service recovered after a fix","args":{"script":"systemctl is-active nginx && curl -fsS http://localhost/health"}},{"title":"Inspect why a unit failed","args":{"script":"journalctl -u myapp -n 50 --no-pager | tail -20"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","{{ args.script }}"]}}]}]},{"id":"showcase","name":"Showcase pack","version":"0.2.14","description":"Synthetic pack that demonstrates every action-schema feature in one place: all arg types, every validation, both parsers, both kinds, opts envelope bounds, and per-action redaction rules. Not a production pack — use it as a reference when authoring real ones.","vendor":"emisar","homepage":"https://emisar.dev/packs/showcase","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/showcase","content_hash":"sha256:1374d67afa20c8727db2c0466fb289ba188c9ad573f6984cf34d2114e454aac2","tarball_url":"https://registry.emisar.dev/v1/packs/showcase/0.2.14/1374d67afa20c8727db2c0466fb289ba188c9ad573f6984cf34d2114e454aac2/pack.tar.gz","requires":{"os":[],"binaries":["bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Reference pack only — every action runs a trivial local command (echo or a bundled script) and authenticates to nothing. No env vars or credentials to provision; do not use it in production.","verify":"showcase.every_arg_type"},"actions":[{"id":"showcase.every_arg_type","title":"One arg of every type","summary":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","description":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","kind":"exec","risk":"low","side_effects":["Runs /bin/echo with the rendered argv.","Touches no files."],"args":[{"name":"mode","type":"string","required":true,"description":"Discrete choice of mode.","validation":{"enum":["fast","slow","balanced"]}},{"name":"identifier","type":"string","required":false,"default":"abc123","description":"Free-form identifier matching a regex.","validation":{"pattern":"^[a-z0-9_]{3,32}$"}},{"name":"note","type":"string","required":false,"default":"","description":"Free-form note attached to the run.","validation":{"max_length":4096}},{"name":"port","type":"integer","required":false,"default":8080,"description":"Listen port, restricted to a known set.","validation":{"allowed":[80,443,8080,8443]}},{"name":"ratio","type":"number","required":false,"default":0.5,"description":"Fractional ratio between 0 and 1.","validation":{"min":0,"max":1}},{"name":"verbose","type":"boolean","required":false,"default":false,"description":"Toggle verbose output. Boolean args have no validation block."},{"name":"window","type":"duration","required":false,"default":"5m","description":"Lookback window; capped at 1 hour.","validation":{"min_duration":"1s","max_duration":"1h0m0s"}},{"name":"tags","type":"string_array","required":false,"default":[],"description":"Free-form tag list. Use {{ args.tags }} in argv to expand.","validation":{"max_items":16}},{"name":"ids","type":"integer_array","required":false,"default":[],"description":"List of numeric ids.","validation":{"max_items":32}}],"examples":[{"title":"Minimal call (only the required arg)","args":{"mode":"fast"}},{"title":"Tags expand into multiple argv elements","args":{"ids":[1,2,3],"mode":"balanced","tags":["red","green","blue"]}}],"search_terms":[],"command":{"binary":"echo","argv":["mode={{ args.mode }}","identifier={{ args.identifier }}","port={{ args.port }}","ratio={{ args.ratio }}","verbose={{ args.verbose }}","window={{ args.window }}","--","{{ args.tags }}","--","{{ args.ids }}"]}},{"id":"showcase.json_output","title":"Parse stdout as JSON, with action-local redaction","summary":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","description":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","kind":"exec","risk":"low","side_effects":["Calls /bin/echo with a synthetic JSON payload.","Does not modify state."],"args":[{"name":"name","type":"string","required":true,"description":"Name to include in the synthetic payload.","validation":{"pattern":"^[a-zA-Z0-9_-]{1,32}$"}}],"examples":[{"title":"Emit a parsed JSON object","args":{"name":"alice"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"name":{"pattern":"^[a-zA-Z0-9_-]{1,32}$","type":"string"},"session_token":{"const":"[REDACTED]"},"status":{"const":"ok"}},"required":["name","session_token","status"],"type":"object"},"command":{"binary":"echo","argv":["{\"name\":\"{{ args.name }}\",\"session_token\":\"sk_live_abcd1234\",\"status\":\"ok\"}"]}},{"id":"showcase.opts_envelope","title":"Demonstrate opts.timeout and opts.max_stdout_bytes clamping","summary":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","description":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","kind":"exec","risk":"low","side_effects":["Sleeps then emits a small payload."],"args":[{"name":"payload","type":"string","required":false,"default":"ok","description":"Free-form payload string echoed at end.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_-]{0,63}$"}}],"examples":[{"title":"Default opts","args":{"payload":"ok"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sleep 1; echo \"$1\"","emisar","{{ args.payload }}"]}},{"id":"showcase.path_validation","title":"Read-only file inspection with path allowlist","summary":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","description":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","kind":"exec","risk":"low","side_effects":["Reads file metadata via stat.","Does not read file contents."],"args":[{"name":"file","type":"path","required":true,"description":"A path under /var/log or /tmp, excluding the denied set.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"]}},{"name":"extras","type":"string_array","required":false,"default":[],"description":"Additional paths to inspect. Every element is validated the same way as `file`: the runner applies the path allow/deny rules and max_length to each element (not just the whole-array validators), so the same /var/log,/tmp containment holds for extras.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"],"max_items":4,"max_length":256}}],"examples":[{"title":"Inspect one allowlisted file","args":{"file":"/var/log/syslog"}},{"title":"Inspect a tmp file with extras","args":{"extras":["/tmp/run.lock"],"file":"/tmp/run.pid"}}],"search_terms":[],"command":{"binary":"stat","argv":["{{ args.file }}","{{ args.extras }}"]}},{"id":"showcase.script_action","title":"Run a packaged shell script","summary":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","description":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","kind":"script","risk":"low","side_effects":["Runs the bundled scripts/echo_args.sh.","Writes nothing."],"args":[{"name":"message","type":"string","required":true,"description":"A string passed to the script as --message.","validation":{"pattern":"^[ -~]{1,80}$"}},{"name":"repeat","type":"integer","required":false,"default":1,"description":"Number of times to echo the message.","validation":{"min":1,"max":5}}],"examples":[{"title":"Echo twice","args":{"message":"hello","repeat":2}}],"search_terms":[]}],"previous_versions":[{"version":"0.2.13","content_hash":"sha256:c2123e8c613e5f59a4174be6365d40936794f86fb72b0a0e1f25ca0ace1fb47f","tarball_url":"https://registry.emisar.dev/v1/packs/showcase/0.2.13/c2123e8c613e5f59a4174be6365d40936794f86fb72b0a0e1f25ca0ace1fb47f/pack.tar.gz","actions":[{"id":"showcase.every_arg_type","title":"One arg of every type","summary":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","description":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","kind":"exec","risk":"low","side_effects":["Runs /bin/echo with the rendered argv.","Touches no files."],"args":[{"name":"mode","type":"string","required":true,"description":"Discrete choice of mode.","validation":{"enum":["fast","slow","balanced"]}},{"name":"identifier","type":"string","required":false,"default":"abc123","description":"Free-form identifier matching a regex.","validation":{"pattern":"^[a-z0-9_]{3,32}$"}},{"name":"note","type":"string","required":false,"default":"","description":"Free-form note attached to the run.","validation":{"max_length":4096}},{"name":"port","type":"integer","required":false,"default":8080,"description":"Listen port, restricted to a known set.","validation":{"allowed":[80,443,8080,8443]}},{"name":"ratio","type":"number","required":false,"default":0.5,"description":"Fractional ratio between 0 and 1.","validation":{"min":0,"max":1}},{"name":"verbose","type":"boolean","required":false,"default":false,"description":"Toggle verbose output. Boolean args have no validation block."},{"name":"window","type":"duration","required":false,"default":"5m","description":"Lookback window; capped at 1 hour.","validation":{"min_duration":"1s","max_duration":"1h0m0s"}},{"name":"tags","type":"string_array","required":false,"default":[],"description":"Free-form tag list. Use {{ args.tags }} in argv to expand.","validation":{"max_items":16}},{"name":"ids","type":"integer_array","required":false,"default":[],"description":"List of numeric ids.","validation":{"max_items":32}}],"examples":[{"title":"Minimal call (only the required arg)","args":{"mode":"fast"}},{"title":"Tags expand into multiple argv elements","args":{"ids":[1,2,3],"mode":"balanced","tags":["red","green","blue"]}}],"search_terms":[],"command":{"binary":"echo","argv":["mode={{ args.mode }}","identifier={{ args.identifier }}","port={{ args.port }}","ratio={{ args.ratio }}","verbose={{ args.verbose }}","window={{ args.window }}","--","{{ args.tags }}","--","{{ args.ids }}"]}},{"id":"showcase.json_output","title":"Parse stdout as JSON, with action-local redaction","summary":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","description":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","kind":"exec","risk":"low","side_effects":["Calls /bin/echo with a synthetic JSON payload.","Does not modify state."],"args":[{"name":"name","type":"string","required":true,"description":"Name to include in the synthetic payload.","validation":{"pattern":"^[a-zA-Z0-9_-]{1,32}$"}}],"examples":[{"title":"Emit a parsed JSON object","args":{"name":"alice"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"name":{"pattern":"^[a-zA-Z0-9_-]{1,32}$","type":"string"},"session_token":{"const":"[REDACTED]"},"status":{"const":"ok"}},"required":["name","session_token","status"],"type":"object"},"command":{"binary":"echo","argv":["{\"name\":\"{{ args.name }}\",\"session_token\":\"sk_live_abcd1234\",\"status\":\"ok\"}"]}},{"id":"showcase.opts_envelope","title":"Demonstrate opts.timeout and opts.max_stdout_bytes clamping","summary":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","description":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","kind":"exec","risk":"low","side_effects":["Sleeps then emits a small payload."],"args":[{"name":"payload","type":"string","required":false,"default":"ok","description":"Free-form payload string echoed at end.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_-]{0,63}$"}}],"examples":[{"title":"Default opts","args":{"payload":"ok"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sleep 1; echo \"$1\"","emisar","{{ args.payload }}"]}},{"id":"showcase.path_validation","title":"Read-only file inspection with path allowlist","summary":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","description":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","kind":"exec","risk":"low","side_effects":["Reads file metadata via stat.","Does not read file contents."],"args":[{"name":"file","type":"path","required":true,"description":"A path under /var/log or /tmp, excluding the denied set.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"]}},{"name":"extras","type":"string_array","required":false,"default":[],"description":"Additional paths to inspect. Every element is validated the same way as `file`: the runner applies the path allow/deny rules and max_length to each element (not just the whole-array validators), so the same /var/log,/tmp containment holds for extras.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"],"max_items":4,"max_length":256}}],"examples":[{"title":"Inspect one allowlisted file","args":{"file":"/var/log/syslog"}},{"title":"Inspect a tmp file with extras","args":{"extras":["/tmp/run.lock"],"file":"/tmp/run.pid"}}],"search_terms":[],"command":{"binary":"stat","argv":["{{ args.file }}","{{ args.extras }}"]}},{"id":"showcase.script_action","title":"Run a packaged shell script","summary":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","description":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","kind":"script","risk":"low","side_effects":["Runs the bundled scripts/echo_args.sh.","Writes nothing."],"args":[{"name":"message","type":"string","required":true,"description":"A string passed to the script as --message.","validation":{"pattern":"^[ -~]{1,80}$"}},{"name":"repeat","type":"integer","required":false,"default":1,"description":"Number of times to echo the message.","validation":{"min":1,"max":5}}],"examples":[{"title":"Echo twice","args":{"message":"hello","repeat":2}}],"search_terms":[]}]},{"version":"0.2.12","content_hash":"sha256:01d321c3fa101f1841f8945f5a9a8d3cbce841221dbb0c73cab8e42e8e9d01c2","tarball_url":"https://registry.emisar.dev/v1/packs/showcase/0.2.12/01d321c3fa101f1841f8945f5a9a8d3cbce841221dbb0c73cab8e42e8e9d01c2/pack.tar.gz","actions":[{"id":"showcase.every_arg_type","title":"One arg of every type","summary":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","description":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","kind":"exec","risk":"low","side_effects":["Runs /bin/echo with the rendered argv.","Touches no files."],"args":[{"name":"mode","type":"string","required":true,"description":"Discrete choice of mode.","validation":{"enum":["fast","slow","balanced"]}},{"name":"identifier","type":"string","required":false,"default":"abc123","description":"Free-form identifier matching a regex.","validation":{"pattern":"^[a-z0-9_]{3,32}$"}},{"name":"note","type":"string","required":false,"default":"","description":"Free-form note attached to the run.","validation":{"max_length":4096}},{"name":"port","type":"integer","required":false,"default":8080,"description":"Listen port, restricted to a known set.","validation":{"allowed":[80,443,8080,8443]}},{"name":"ratio","type":"number","required":false,"default":0.5,"description":"Fractional ratio between 0 and 1.","validation":{"min":0,"max":1}},{"name":"verbose","type":"boolean","required":false,"default":false,"description":"Toggle verbose output. Boolean args have no validation block."},{"name":"window","type":"duration","required":false,"default":"5m","description":"Lookback window; capped at 1 hour.","validation":{"min_duration":"1s","max_duration":"1h0m0s"}},{"name":"tags","type":"string_array","required":false,"default":[],"description":"Free-form tag list. Use {{ args.tags }} in argv to expand.","validation":{"max_items":16}},{"name":"ids","type":"integer_array","required":false,"default":[],"description":"List of numeric ids.","validation":{"max_items":32}}],"examples":[{"title":"Minimal call (only the required arg)","args":{"mode":"fast"}},{"title":"Tags expand into multiple argv elements","args":{"ids":[1,2,3],"mode":"balanced","tags":["red","green","blue"]}}],"search_terms":[],"command":{"binary":"echo","argv":["mode={{ args.mode }}","identifier={{ args.identifier }}","port={{ args.port }}","ratio={{ args.ratio }}","verbose={{ args.verbose }}","window={{ args.window }}","--","{{ args.tags }}","--","{{ args.ids }}"]}},{"id":"showcase.json_output","title":"Parse stdout as JSON, with action-local redaction","summary":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","description":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","kind":"exec","risk":"low","side_effects":["Calls /bin/echo with a synthetic JSON payload.","Does not modify state."],"args":[{"name":"name","type":"string","required":true,"description":"Name to include in the synthetic payload.","validation":{"pattern":"^[a-zA-Z0-9_-]{1,32}$"}}],"examples":[{"title":"Emit a parsed JSON object","args":{"name":"alice"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"name":{"pattern":"^[a-zA-Z0-9_-]{1,32}$","type":"string"},"session_token":{"const":"[REDACTED]"},"status":{"const":"ok"}},"required":["name","session_token","status"],"type":"object"},"command":{"binary":"echo","argv":["{\"name\":\"{{ args.name }}\",\"session_token\":\"sk_live_abcd1234\",\"status\":\"ok\"}"]}},{"id":"showcase.opts_envelope","title":"Demonstrate opts.timeout and opts.max_stdout_bytes clamping","summary":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","description":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","kind":"exec","risk":"low","side_effects":["Sleeps then emits a small payload."],"args":[{"name":"payload","type":"string","required":false,"default":"ok","description":"Free-form payload string echoed at end.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_-]{0,63}$"}}],"examples":[{"title":"Default opts","args":{"payload":"ok"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sleep 1; echo \"$1\"","emisar","{{ args.payload }}"]}},{"id":"showcase.path_validation","title":"Read-only file inspection with path allowlist","summary":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","description":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","kind":"exec","risk":"low","side_effects":["Reads file metadata via stat.","Does not read file contents."],"args":[{"name":"file","type":"path","required":true,"description":"A path under /var/log or /tmp, excluding the denied set.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"]}},{"name":"extras","type":"string_array","required":false,"default":[],"description":"Additional paths to inspect. Every element is validated the same way as `file`: the runner applies the path allow/deny rules and max_length to each element (not just the whole-array validators), so the same /var/log,/tmp containment holds for extras.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"],"max_items":4,"max_length":256}}],"examples":[{"title":"Inspect one allowlisted file","args":{"file":"/var/log/syslog"}},{"title":"Inspect a tmp file with extras","args":{"extras":["/tmp/run.lock"],"file":"/tmp/run.pid"}}],"search_terms":[],"command":{"binary":"stat","argv":["{{ args.file }}","{{ args.extras }}"]}},{"id":"showcase.script_action","title":"Run a packaged shell script","summary":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","description":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","kind":"script","risk":"low","side_effects":["Runs the bundled scripts/echo_args.sh.","Writes nothing."],"args":[{"name":"message","type":"string","required":true,"description":"A string passed to the script as --message.","validation":{"pattern":"^[ -~]{1,80}$"}},{"name":"repeat","type":"integer","required":false,"default":1,"description":"Number of times to echo the message.","validation":{"min":1,"max":5}}],"examples":[{"title":"Echo twice","args":{"message":"hello","repeat":2}}],"search_terms":[]}]},{"version":"0.2.11","content_hash":"sha256:5a739b2833575ad2bf17568b194376cdef9d84d7e9c099ee5edc3b8c65d46596","tarball_url":"https://registry.emisar.dev/v1/packs/showcase/0.2.11/5a739b2833575ad2bf17568b194376cdef9d84d7e9c099ee5edc3b8c65d46596/pack.tar.gz","actions":[{"id":"showcase.every_arg_type","title":"One arg of every type","summary":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","description":"Show a reference action: one argument of every supported type with a representative validation. Look here when you need to remember the YAML shape for `string_array`, `integer_array`, `duration`, etc.","kind":"exec","risk":"low","side_effects":["Runs /bin/echo with the rendered argv.","Touches no files."],"args":[{"name":"mode","type":"string","required":true,"description":"Discrete choice of mode.","validation":{"enum":["fast","slow","balanced"]}},{"name":"identifier","type":"string","required":false,"default":"abc123","description":"Free-form identifier matching a regex.","validation":{"pattern":"^[a-z0-9_]{3,32}$"}},{"name":"note","type":"string","required":false,"default":"","description":"Free-form note attached to the run.","validation":{"max_length":4096}},{"name":"port","type":"integer","required":false,"default":8080,"description":"Listen port, restricted to a known set.","validation":{"allowed":[80,443,8080,8443]}},{"name":"ratio","type":"number","required":false,"default":0.5,"description":"Fractional ratio between 0 and 1.","validation":{"min":0,"max":1}},{"name":"verbose","type":"boolean","required":false,"default":false,"description":"Toggle verbose output. Boolean args have no validation block."},{"name":"window","type":"duration","required":false,"default":"5m","description":"Lookback window; capped at 1 hour.","validation":{"min_duration":"1s","max_duration":"1h0m0s"}},{"name":"tags","type":"string_array","required":false,"default":[],"description":"Free-form tag list. Use {{ args.tags }} in argv to expand.","validation":{"max_items":16}},{"name":"ids","type":"integer_array","required":false,"default":[],"description":"List of numeric ids.","validation":{"max_items":32}}],"examples":[{"title":"Minimal call (only the required arg)","args":{"mode":"fast"}},{"title":"Tags expand into multiple argv elements","args":{"ids":[1,2,3],"mode":"balanced","tags":["red","green","blue"]}}],"search_terms":[],"command":{"binary":"echo","argv":["mode={{ args.mode }}","identifier={{ args.identifier }}","port={{ args.port }}","ratio={{ args.ratio }}","verbose={{ args.verbose }}","window={{ args.window }}","--","{{ args.tags }}","--","{{ args.ids }}"]}},{"id":"showcase.json_output","title":"Parse stdout as JSON, with action-local redaction","summary":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","description":"Demonstrate `parser: json` plus an extra regex redaction rule scoped to this action. The rule sits *in front of* the global rules — useful when an action emits a known secret shape that the global rules don't cover.","kind":"exec","risk":"low","side_effects":["Calls /bin/echo with a synthetic JSON payload.","Does not modify state."],"args":[{"name":"name","type":"string","required":true,"description":"Name to include in the synthetic payload.","validation":{"pattern":"^[a-zA-Z0-9_-]{1,32}$"}}],"examples":[{"title":"Emit a parsed JSON object","args":{"name":"alice"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"name":{"pattern":"^[a-zA-Z0-9_-]{1,32}$","type":"string"},"session_token":{"const":"[REDACTED]"},"status":{"const":"ok"}},"required":["name","session_token","status"],"type":"object"},"command":{"binary":"echo","argv":["{\"name\":\"{{ args.name }}\",\"session_token\":\"sk_live_abcd1234\",\"status\":\"ok\"}"]}},{"id":"showcase.opts_envelope","title":"Demonstrate opts.timeout and opts.max_stdout_bytes clamping","summary":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","description":"Sleep briefly and emit a fixed payload. The interesting bit is the execution/output envelope: cloud-supplied opts.timeout is clamped to [2s, 30s] regardless of what the LLM asked for, and stdout caps are bounded between 1 KiB and 64 KiB.","kind":"exec","risk":"low","side_effects":["Sleeps then emits a small payload."],"args":[{"name":"payload","type":"string","required":false,"default":"ok","description":"Free-form payload string echoed at end.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_-]{0,63}$"}}],"examples":[{"title":"Default opts","args":{"payload":"ok"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","sleep 1; echo \"$1\"","emisar","{{ args.payload }}"]}},{"id":"showcase.path_validation","title":"Read-only file inspection with path allowlist","summary":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","description":"Show a reference action for path-typed arguments. Demonstrates allowed prefixes plus an explicit deny list. The combined effect: the caller may inspect anything under /var/log or /tmp, except /var/log/secure and anything under /tmp/private.","kind":"exec","risk":"low","side_effects":["Reads file metadata via stat.","Does not read file contents."],"args":[{"name":"file","type":"path","required":true,"description":"A path under /var/log or /tmp, excluding the denied set.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"]}},{"name":"extras","type":"string_array","required":false,"default":[],"description":"Additional paths to inspect. Every element is validated the same way as `file`: the runner applies the path allow/deny rules and max_length to each element (not just the whole-array validators), so the same /var/log,/tmp containment holds for extras.","validation":{"denied_paths":["/var/log/secure"],"allowed_prefixes":["/var/log","/tmp"],"denied_prefixes":["/tmp/private"],"max_items":4,"max_length":256}}],"examples":[{"title":"Inspect one allowlisted file","args":{"file":"/var/log/syslog"}},{"title":"Inspect a tmp file with extras","args":{"extras":["/tmp/run.lock"],"file":"/tmp/run.pid"}}],"search_terms":[],"command":{"binary":"stat","argv":["{{ args.file }}","{{ args.extras }}"]}},{"id":"showcase.script_action","title":"Run a packaged shell script","summary":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","description":"Call a packaged shell script. The interpreter is explicit (/bin/bash), the script path is resolved relative to the pack root, and the script's SHA-256 is journaled with every invocation so tampering is detectable after the fact.","kind":"script","risk":"low","side_effects":["Runs the bundled scripts/echo_args.sh.","Writes nothing."],"args":[{"name":"message","type":"string","required":true,"description":"A string passed to the script as --message.","validation":{"pattern":"^[ -~]{1,80}$"}},{"name":"repeat","type":"integer","required":false,"default":1,"description":"Number of times to echo the message.","validation":{"min":1,"max":5}}],"examples":[{"title":"Echo twice","args":{"message":"hello","repeat":2}}],"search_terms":[]}]}]},{"id":"snmp","name":"SNMP (net-snmp)","version":"0.2.4","description":"Read a network device over SNMP with the net-snmp CLI — system group, interface table, BGP peers (BGP4-MIB) and OSPF neighbors / general group (OSPF-MIB), plus a generic single-OID get and a bounded subtree walk. The routing reads exist to give operators visibility into BGP / OSPF state on devices this control plane can't reach by a native API — e.g. a pfSense + FRR edge firewall, where the REST API exposes no routing-protocol state. All read-only.","vendor":"emisar","homepage":"https://emisar.dev/packs/snmp","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/snmp","content_hash":"sha256:b63c4b702fcfd4669ff8b7387693ea478a997cae6be0053b69b1dddd4dcdee08","tarball_url":"https://registry.emisar.dev/v1/packs/snmp/0.2.4/b63c4b702fcfd4669ff8b7387693ea478a997cae6be0053b69b1dddd4dcdee08/pack.tar.gz","requires":{"os":["linux"],"binaries":["snmpget","snmpbulkwalk"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Every action runs a net-snmp client (snmpget / snmpbulkwalk) against the {{ args.host }} you pass, after requiring that exact destination in `SNMP_ALLOWED_HOSTS`. Install net-snmp on the runner host (Debian: apt-get install snmp), enable SNMP on each target device, and set the credentials below.","env":[{"name":"SNMP_ALLOWED_HOSTS","required":true,"description":"Comma-separated exact device hostnames, IP addresses, or `host:port` destinations that actions may target. Matching is ASCII case-insensitive; entries do not accept wildcards, CIDRs, URLs, or spaces.","example":"edge01.mgmt,10.20.0.1:1161"},{"name":"SNMP_VERSION","description":"SNMP version — \"1\", \"2c\" (default), or \"3\". The table reads use GETBULK, so they need 2c or 3. Prefer 3 (authPriv) on any untrusted path: v1/v2c send the community in cleartext on the wire.","default":"2c"},{"name":"SNMP_COMMUNITY","description":"The read-only community string (SNMP v1/v2c). Written to a transient snmp.conf the tool reads via SNMPCONFPATH, so it never appears in the process arguments or the audit log. Use a least-privilege RO community."},{"name":"SNMP_USER","description":"SNMPv3 security (user) name."},{"name":"SNMP_LEVEL","description":"SNMPv3 security level: noAuthNoPriv, authNoPriv, or authPriv (default).","default":"authPriv"},{"name":"SNMP_AUTH_PROTO","description":"SNMPv3 authentication protocol (e.g. SHA, SHA-256, MD5).","default":"SHA"},{"name":"SNMP_AUTH_PASS","description":"SNMPv3 authentication passphrase. Streamed via snmp.conf, never in argv."},{"name":"SNMP_PRIV_PROTO","description":"SNMPv3 privacy (encryption) protocol (e.g. AES, AES-256, DES).","default":"AES"},{"name":"SNMP_PRIV_PASS","description":"SNMPv3 privacy passphrase. Streamed via snmp.conf, never in argv."}],"notes":["`SNMP_ALLOWED_HOSTS` and any SNMP credentials or protocol settings you set (`SNMP_COMMUNITY`, `SNMP_USER`, `SNMP_AUTH_PASS`, `SNMP_PRIV_PASS`, `SNMP_VERSION`, `SNMP_LEVEL`, and the protocol choices) must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so a variable present on the host but not inherited is silently dropped and the call is refused or fails authentication.","Actions query by NUMERIC OID so they work without MIB files (Debian's `snmp` package ships none by default — `mibs :` is commented out). Output is therefore numeric too; each routing action's description maps the columns and decodes the state enums. Install `snmp-mibs-downloader` on the runner for symbolic names if you prefer.","Enable SNMP on the device first. pfSense: Services → SNMP (set an RO community, bind it to the management interface, not WAN). The host arg is the device address; an unreachable device or wrong community fails the action (non-zero exit), it is not reported as empty.","BGP4-MIB / OSPF-MIB are not served by the base snmpd — FRR exports them over AgentX. On the firewall/router, enable AgentX in FRR (`agentx` in the daemon config) and run bgpd/ospfd with the SNMP module, and set `master agentx` in snmpd.conf. Without that, bgp_peers / ospf_* return nothing even though SNMP itself works (snmp.system will still answer).","This pack only reads. SNMP SET (writes) is intentionally not implemented — community-based SET is a notorious abuse surface, and emisar mutators belong in device-native, auditable packs."],"verify":"snmp.system"},"actions":[{"id":"snmp.bgp_peers","title":"snmpwalk BGP4-MIB bgpPeerTable (1.3.6.1.2.1.15.3)","summary":"List BGP peers from BGP4-MIB bgpPeerTable — per-peer bgpPeerState (.2: 1=idle 2=connect 3=active 4=opensent 5=openconfirm 6=established), bgpPeerAdminStatus (.3: 1=stop 2=start), bgpPeerRemoteAddr (.7), bgpPeerRemoteAs (.9), in/out updates (.10/.11), and bgpPeerFsmEstablishedTime (.16). The right read for \"is the BGP session up?\" on a router or firewall (e.g. pfSense + FRR) that this control plane can't reach by a native API. Walks 1.3.6.1.2.1.15.3.","description":"List BGP peers from BGP4-MIB bgpPeerTable — per-peer bgpPeerState (.2: 1=idle 2=connect 3=active 4=opensent 5=openconfirm 6=established), bgpPeerAdminStatus (.3: 1=stop 2=start), bgpPeerRemoteAddr (.7), bgpPeerRemoteAs (.9), in/out updates (.10/.11), and bgpPeerFsmEstablishedTime (.16). The right read for \"is the BGP session up?\" on a router or firewall (e.g. pfSense + FRR) that this control plane can't reach by a native API. Walks 1.3.6.1.2.1.15.3.","kind":"script","risk":"low","side_effects":["One read-only SNMP walk of the BGP peer table.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}}],"examples":[{"title":"BGP peers on the edge firewall","args":{"host":"10.11.13.1"}}],"search_terms":[]},{"id":"snmp.get","title":"snmpget a single OID","summary":"Get a single SNMP object by OID — one snmpget. Use for a specific scalar the curated reads don't cover (e.g. a vendor MIB value). Give a numeric OID like 1.3.6.1.2.1.1.5.0, or a symbolic one (SNMPv2-MIB::sysName.0) if the device's MIBs are installed on the runner.","description":"Get a single SNMP object by OID — one snmpget. Use for a specific scalar the curated reads don't cover (e.g. a vendor MIB value). Give a numeric OID like 1.3.6.1.2.1.1.5.0, or a symbolic one (SNMPv2-MIB::sysName.0) if the device's MIBs are installed on the runner.","kind":"script","risk":"low","side_effects":["One read-only SNMP GET of a single object.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"oid","type":"string","required":true,"description":"The object OID — numeric (1.3.6.1.2.1.1.5.0) or symbolic (sysName.0).","validation":{"pattern":"^[.A-Za-z0-9][A-Za-z0-9.:_\\-]{0,127}$"}}],"examples":[{"title":"Get sysName","args":{"host":"10.11.13.1","oid":"1.3.6.1.2.1.1.5.0"}}],"search_terms":[]},{"id":"snmp.interfaces","title":"snmpwalk IF-MIB ifTable (1.3.6.1.2.1.2.2)","summary":"List a device's interfaces from IF-MIB ifTable — per-interface ifDescr (.2), ifType (.3), ifSpeed (.5), ifAdminStatus (.7: 1=up 2=down), ifOperStatus (.8: 1=up 2=down), and in/out octets (.10/.16) and errors (.14/.20). Use to spot a down or errored link. Walks 1.3.6.1.2.1.2.2.","description":"List a device's interfaces from IF-MIB ifTable — per-interface ifDescr (.2), ifType (.3), ifSpeed (.5), ifAdminStatus (.7: 1=up 2=down), ifOperStatus (.8: 1=up 2=down), and in/out octets (.10/.16) and errors (.14/.20). Use to spot a down or errored link. Walks 1.3.6.1.2.1.2.2.","kind":"script","risk":"low","side_effects":["One read-only SNMP walk of the interface table.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}}],"examples":[{"title":"Interface table of a switch","args":{"host":"10.11.13.1"}}],"search_terms":[]},{"id":"snmp.ospf_general","title":"snmpwalk OSPF-MIB ospfGeneralGroup (1.3.6.1.2.1.14.1)","summary":"Show the OSPF general group from OSPF-MIB — ospfRouterId (.1), ospfAdminStat (.2: 1=enabled 2=disabled), ospfVersionNumber (.3), and the area-border / AS-border router flags (.4/.5). Use to confirm OSPF is enabled and read the router id. Walks 1.3.6.1.2.1.14.1.","description":"Show the OSPF general group from OSPF-MIB — ospfRouterId (.1), ospfAdminStat (.2: 1=enabled 2=disabled), ospfVersionNumber (.3), and the area-border / AS-border router flags (.4/.5). Use to confirm OSPF is enabled and read the router id. Walks 1.3.6.1.2.1.14.1.","kind":"script","risk":"low","side_effects":["One read-only SNMP walk of the OSPF general group.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}}],"examples":[{"title":"OSPF status / router id","args":{"host":"10.11.13.1"}}],"search_terms":[]},{"id":"snmp.ospf_neighbors","title":"snmpwalk OSPF-MIB ospfNbrTable (1.3.6.1.2.1.14.10)","summary":"List OSPF neighbors from OSPF-MIB ospfNbrTable — per-neighbor ospfNbrIpAddr (.1), ospfNbrRtrId (.3), and ospfNbrState (.6: 1=down 2=attempt 3=init 4=twoWay 5=exchangeStart 6=exchange 7=loading 8=full). A healthy adjacency is 8=full (or 4=twoWay on a DR-other). Use to confirm OSPFv2 adjacencies. Walks 1.3.6.1.2.1.14.10. (OSPFv3 lives in OSPFV3-MIB — use snmp.walk.)","description":"List OSPF neighbors from OSPF-MIB ospfNbrTable — per-neighbor ospfNbrIpAddr (.1), ospfNbrRtrId (.3), and ospfNbrState (.6: 1=down 2=attempt 3=init 4=twoWay 5=exchangeStart 6=exchange 7=loading 8=full). A healthy adjacency is 8=full (or 4=twoWay on a DR-other). Use to confirm OSPFv2 adjacencies. Walks 1.3.6.1.2.1.14.10. (OSPFv3 lives in OSPFV3-MIB — use snmp.walk.)","kind":"script","risk":"low","side_effects":["One read-only SNMP walk of the OSPF neighbor table.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}}],"examples":[{"title":"OSPF neighbors on a router","args":{"host":"10.11.13.1"}}],"search_terms":[]},{"id":"snmp.system","title":"snmpwalk system group (1.3.6.1.2.1.1)","summary":"Show the SNMP system group of a device — sysDescr (model/OS), sysObjectID, sysUpTime, sysContact, sysName, sysLocation. The first stop to confirm SNMP works and identify what the device is. Walks 1.3.6.1.2.1.1.","description":"Show the SNMP system group of a device — sysDescr (model/OS), sysObjectID, sysUpTime, sysContact, sysName, sysLocation. The first stop to confirm SNMP works and identify what the device is. Walks 1.3.6.1.2.1.1.","kind":"script","risk":"low","side_effects":["One read-only SNMP walk of the system group.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}}],"examples":[{"title":"System group of a firewall","args":{"host":"10.11.13.1"}}],"search_terms":[]},{"id":"snmp.walk","title":"snmpwalk an OID subtree","summary":"Walk an SNMP subtree by root OID — one snmpbulkwalk (requires SNMP v2c or v3). Use to read a table or MIB the curated reads don't cover (e.g. OSPFV3-MIB 1.3.6.1.2.1.191, or a vendor table). Output is capped, so a very large subtree is truncated; narrow the root OID. Give a numeric OID, or a symbolic one if the device's MIBs are installed on the runner.","description":"Walk an SNMP subtree by root OID — one snmpbulkwalk (requires SNMP v2c or v3). Use to read a table or MIB the curated reads don't cover (e.g. OSPFV3-MIB 1.3.6.1.2.1.191, or a vendor table). Output is capped, so a very large subtree is truncated; narrow the root OID. Give a numeric OID, or a symbolic one if the device's MIBs are installed on the runner.","kind":"script","risk":"low","side_effects":["One read-only SNMP walk of the given subtree.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Target device hostname or IP (optionally host:port).","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-:]{0,252}$"}},{"name":"oid","type":"string","required":true,"description":"Root OID of the subtree — numeric (1.3.6.1.2.1.4) or symbolic (ipAddrTable).","validation":{"pattern":"^[.A-Za-z0-9][A-Za-z0-9.:_\\-]{0,127}$"}}],"examples":[{"title":"Walk the IP address table","args":{"host":"10.11.13.1","oid":"1.3.6.1.2.1.4.20"}}],"search_terms":[]}],"retired_below":"0.2.4"},{"id":"spark","name":"Apache Spark","version":"0.1.3","description":"Governed Apache Spark operations over the HTTP surfaces a cluster already exposes: the monitoring REST API (/api/v1) on a live driver UI and on the history server — applications, jobs, stages with task-quantile summaries and task lists, executors with memory and GC, SQL executions, cached RDDs, and live executor thread dumps — plus the standalone master's cluster state and the standalone REST submission server. The controls are the ones an operator reaches for during an incident: kill a runaway job or stage on the driver, kill an application or driver from the master, decommission a worker, and kill a REST submission. Reads name their source (driver or history) because only a live driver knows a running application and only the history server keeps a finished one.","vendor":"emisar","homepage":"https://emisar.dev/packs/spark","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/spark","content_hash":"sha256:a1098cf998ec5a968fa64c42927bbd3d203a52e65cef6ec5bfc0ba5384d65126","tarball_url":"https://registry.emisar.dev/v1/packs/spark/0.1.3/a1098cf998ec5a968fa64c42927bbd3d203a52e65cef6ec5bfc0ba5384d65126/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","bash"]},"detect":{"binaries":["spark-submit","spark-class"],"processes":[],"ports":[4040,7077,8080,18080]},"setup":{"summary":"Every action is one HTTP call to a Spark web endpoint over curl on the runner host. Point each URL at the surface this host can reach; an action only needs the ones it uses. `SPARK_API_TOKEN`, when a reverse proxy in front of the UI requires one, is sent as an Authorization header over curl stdin and never reaches the process arguments.","env":[{"name":"SPARK_HISTORY_URL","description":"Base URL of the Spark history server. Serves /api/v1 for applications that have finished (and, with status=running, for ones still in flight that have written an event log).","default":"http://127.0.0.1:18080","example":"http://spark-history.internal:18080"},{"name":"SPARK_UI_URL","description":"Base URL of a live driver's web UI. Serves /api/v1 for the one application that driver is running, and is the only surface with executor thread dumps and the job and stage kill endpoints.","default":"http://127.0.0.1:4040","example":"http://10.0.4.21:4040"},{"name":"SPARK_MASTER_URL","description":"Base URL of the standalone master's web UI, for cluster state and for killing an application, a driver, or a worker.","default":"http://127.0.0.1:8080","example":"http://spark-master.internal:8080"},{"name":"SPARK_REST_URL","description":"Base URL of the standalone REST submission server, for submission status and kill. Disabled by default; the cluster must set spark.master.rest.enabled true.","default":"http://127.0.0.1:6066","example":"http://spark-master.internal:6066"},{"name":"SPARK_API_TOKEN","description":"Bearer token for a Spark UI published behind an authenticating proxy. Sent as the Authorization header over curl stdin. Leave unset for a cluster reached directly."}],"notes":["Any SPARK_* variable you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so a variable present on the host but not allowlisted is silently dropped and the action falls back to its local default.","A driver UI serves exactly one application and stops existing when that application ends, so its port is reused by whatever runs next. Confirm the application id from spark.applications with source driver before acting on a job or stage.","The job and stage kill endpoints need spark.ui.killEnabled (true by default) and, where ACLs are on, a modify-permitted user. The master's kill endpoints need spark.ui.killEnabled on the master; worker decommissioning additionally needs spark.decommission.enabled.","spark.environment returns the Spark configuration and runtime, with JVM system properties and the classpath dropped on the host. Spark's own spark.redaction.regex masks the property values it recognizes — a credential stored under a key that pattern does not match is still returned, which is why the action is high risk.","Spark on YARN or Kubernetes: point `SPARK_UI_URL` at the driver's UI (through the YARN proxy or a port-forward) and `SPARK_HISTORY_URL` at the history server. The master and submission actions are standalone-only."],"verify":"spark.master_state"},"actions":[{"id":"spark.application","title":"GET /api/v1/applications/{app_id}","summary":"Show one Spark application — its name, user, and every attempt with start time, end time, duration, and whether it completed. Read it to confirm an application id and see whether the run you care about finished or is still going.","description":"Show one Spark application — its name, user, and every attempt with start time, end time, duration, and whether it completed. Read it to confirm an application id and see whether the run you care about finished or is still going.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, e.g. app-20260805120000-0001 or application_1754_0007.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"One application from the history server","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark application detail","app duration","did the app finish"]},{"id":"spark.applications","title":"List Spark applications (GET /api/v1/applications)","summary":"List Spark applications with their id, name, user, start and end times, and attempts. Against the history server this is the record of what ran; against a live driver it returns the one application that driver is running. Every other action in this pack takes the app_id this returns.","description":"List Spark applications with their id, name, user, start and end times, and attempts. Against the history server this is the record of what ran; against a live driver it returns the one application that driver is running. Every other action in this pack takes the app_id this returns.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to applications that are still running or have completed. Empty returns both. On the history server, running means an application whose event log is still open.","validation":{"enum":["","running","completed"]}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Applications returned.","validation":{"min":1,"max":200}},{"name":"min_date","type":"string","required":false,"default":"","description":"Only applications that started at or after this date, e.g. 2026-08-05 or 2026-08-05T00:00:00.000GMT.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,3})?(GMT|Z)?)?)?$","max_length":32}}],"examples":[{"title":"Recent applications from the history server","args":{}},{"title":"The application running on this driver","args":{"source":"driver"}},{"title":"Applications still in flight","args":{"status":"running"}}],"search_terms":["list spark applications","which app is running","spark app id","completed applications"]},{"id":"spark.environment","title":"Dump an application's Spark configuration (GET .../environment)","summary":"Dump the Spark configuration an application is running with, plus its runtime versions and resource profiles.","description":"Dump the Spark configuration an application is running with, plus its runtime versions and resource profiles. Answers \"what settings did this job actually get\" when a tuning change did not take effect. High risk because it is a configuration dump: Spark's own spark.redaction.regex masks the property values it recognizes, and the JVM system properties and classpath are dropped on the runner host, but an object-store key or keystore password stored under a property name that pattern does not match is returned as configured.","kind":"script","risk":"high","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","Returns Spark configuration properties, which can carry credentials the redaction pattern does not match.","JVM system properties and the classpath are removed on the runner host."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"The configuration one application ran with","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark config","which settings","spark.sql.shuffle.partitions","executor memory setting","runtime versions"]},{"id":"spark.executor_threads","title":"Dump an executor's threads (GET .../executors/{executor_id}/threads)","summary":"Dump the stack traces of every thread in one live executor. This is the read for a task that is running but making no progress — the stack says whether it is blocked on a lock, waiting on a shuffle fetch, or spinning in user code. Only a live driver serves it; the history server does not. Heavier than the other reads: collecting the dump briefly pauses the executor's threads.","description":"Dump the stack traces of every thread in one live executor. This is the read for a task that is running but making no progress — the stack says whether it is blocked on a lock, waiting on a shuffle fetch, or spinning in user code. Only a live driver serves it; the history server does not. Heavier than the other reads: collecting the dump briefly pauses the executor's threads.","kind":"script","risk":"medium","side_effects":["One HTTP GET to the live driver, which asks the executor for a thread dump.","Read-only — no application, job, or executor state is changed.","Briefly pauses the executor's threads while stacks are collected.","Returns no application data — stack frames only."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications with source driver.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"executor_id","type":"string","required":true,"description":"Executor id, from spark.executors. \"driver\" dumps the driver's own threads.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Why executor 1 is not progressing","args":{"app_id":"app-20260805120000-0001","executor_id":"1"}},{"title":"The driver's own threads","args":{"app_id":"app-20260805120000-0001","executor_id":"driver"}}],"search_terms":["thread dump","stuck task","deadlock","executor hung","no progress"]},{"id":"spark.executors","title":"List an application's executors (GET .../executors)","summary":"List an application's executors with cores, active and completed tasks, failed tasks, GC time, storage memory used against total, disk used, and their host and log URLs. Read it when an application is slow or losing work: a single executor with most of the failed tasks names the bad host.","description":"List an application's executors with cores, active and completed tasks, failed tasks, GC time, storage memory used against total, disk used, and their host and log URLs. Read it when an application is slow or losing work: a single executor with most of the failed tasks names the bad host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"include_removed","type":"string","required":false,"default":"false","description":"Include executors that have already been removed (the allexecutors endpoint). That is what shows an executor lost mid-run, which the active list no longer mentions.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Active executors","args":{"app_id":"app-20260805120000-0001"}},{"title":"Including executors that were lost","args":{"app_id":"app-20260805120000-0001","include_removed":"true"}}],"search_terms":["spark executors","executor memory","lost executor","gc time","executor failures"]},{"id":"spark.job","title":"GET /api/v1/applications/{app_id}/jobs/{job_id}","summary":"Show one Spark job — status, timing, the stage ids it owns, and its task counts including failed and killed. Read it after spark.jobs narrows to the job you care about, then follow its stage ids into spark.stage.","description":"Show one Spark job — status, timing, the stage ids it owns, and its task counts including failed and killed. Read it after spark.jobs narrows to the job you care about, then follow its stage ids into spark.stage.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"job_id","type":"integer","required":true,"description":"Job id, from spark.jobs.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"One job","args":{"app_id":"app-20260805120000-0001","job_id":3}}],"search_terms":["spark job detail","job stages","job failure reason"]},{"id":"spark.job_kill","title":"Kill a running Spark job (POST /jobs/job/kill on the driver UI)","summary":"Kill one running job in the application on the live driver UI. Every task in the job is cancelled and the job is marked failed; whatever the job had already written stays written, so a partially completed output is the normal outcome. The action reads the job back afterwards and returns its state, so a request against an already-finished job is visible rather than assumed. Needs spark.ui.killEnabled, which is on by default.","description":"Kill one running job in the application on the live driver UI. Every task in the job is cancelled and the job is marked failed; whatever the job had already written stays written, so a partially completed output is the normal outcome. The action reads the job back afterwards and returns its state, so a request against an already-finished job is visible rather than assumed. Needs spark.ui.killEnabled, which is on by default.","kind":"script","risk":"high","side_effects":["Cancels every running task in the job; the job ends as failed.","Partial output the job already wrote is left in place.","The application keeps running; only this job is cancelled.","Whether the job was running is reported by reading it back, not assumed."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job id to kill, from spark.jobs with source driver.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Kill a job that will never finish","args":{"job_id":12}}],"search_terms":["kill spark job","cancel job","stop runaway job","runaway query"]},{"id":"spark.jobs","title":"List an application's jobs (GET /api/v1/applications/{app_id}/jobs)","summary":"List a Spark application's jobs with their status, submission time, duration, and task counts — completed, active, skipped, and failed. Filter by `status: failed` to find the job that broke, or `status: running` to see what a stuck application is still working on.","description":"List a Spark application's jobs with their status, submission time, duration, and task counts — completed, active, skipped, and failed. Filter by `status: failed` to find the job that broke, or `status: running` to see what a stuck application is still working on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to jobs in this state. Empty returns every job.","validation":{"enum":["","running","succeeded","failed","unknown"]}}],"examples":[{"title":"Every job in an application","args":{"app_id":"app-20260805120000-0001"}},{"title":"The failed jobs of a live application","args":{"app_id":"app-20260805120000-0001","source":"driver","status":"failed"}}],"search_terms":["spark jobs","failed job","running job","what is the app doing"]},{"id":"spark.master_app_kill","title":"Kill an application from the standalone master (POST /app/kill)","summary":"Kill one whole application on a Spark standalone master. Its driver and every executor are terminated and its cores and memory return to the cluster — which is the point when one application is starving everything else — but the application's work stops wherever it was, so partial output stays partial. The action reads the master's state back and reports whether the application is still active.","description":"Kill one whole application on a Spark standalone master. Its driver and every executor are terminated and its cores and memory return to the cluster — which is the point when one application is starving everything else — but the application's work stops wherever it was, so partial output stays partial. The action reads the master's state back and reports whether the application is still active.","kind":"script","risk":"high","side_effects":["Terminates the application's driver and every one of its executors.","In-flight work is lost; whatever was already written stays written.","Frees the application's cores and memory for other applications.","Whether the application ended is reported by reading the master back, not assumed."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id to kill, e.g. app-20260805120000-0001, from spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill the application that is holding every core","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["kill spark application","free up cores","stop the app","application starving the cluster"]},{"id":"spark.master_driver_kill","title":"Kill a cluster-mode driver from the standalone master (POST /driver/kill)","summary":"Kill one cluster-mode driver on a Spark standalone master. The driver process and the application it runs are terminated. Use it for a submitted job whose client is long gone — a driver stuck in a retry loop, or one submitted by mistake. The action reads the master's state back and reports whether the driver is still active.","description":"Kill one cluster-mode driver on a Spark standalone master. The driver process and the application it runs are terminated. Use it for a submitted job whose client is long gone — a driver stuck in a retry loop, or one submitted by mistake. The action reads the master's state back and reports whether the driver is still active.","kind":"script","risk":"high","side_effects":["Terminates the driver process and the application it is running.","In-flight work is lost; whatever was already written stays written.","A driver submitted with supervise is not restarted after an explicit kill.","Whether the driver ended is reported by reading the master back, not assumed."],"args":[{"name":"driver_id","type":"string","required":true,"description":"Driver id to kill, e.g. driver-20260805120000-0003, from spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a driver stuck restarting","args":{"driver_id":"driver-20260805120000-0003"}}],"search_terms":["kill spark driver","stop cluster mode job","driver retry loop"]},{"id":"spark.master_state","title":"Show standalone cluster state (GET /json/ on the master)","summary":"Show a Spark standalone master's cluster state — every worker with its state, cores and memory used against total, the running and completed applications with the resources each holds, and any submitted drivers. This is the capacity read: an application stuck in WAITING with no free cores means the cluster is full, not that the application is broken.","description":"Show a Spark standalone master's cluster state — every worker with its state, cores and memory used against total, the running and completed applications with the resources each holds, and any submitted drivers. This is the capacity read: an application stuck in WAITING with no free cores means the cluster is full, not that the application is broken.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the standalone master's web UI.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Cluster capacity and what is using it","args":{}}],"search_terms":["spark cluster state","workers alive","free cores","app waiting","standalone master"]},{"id":"spark.master_worker_decommission","title":"Decommission a standalone worker host (POST /workers/kill on the master)","summary":"Decommission every standalone worker on one host. Spark stops scheduling new tasks there and migrates shuffle and cached blocks off before the executors go away, which is the graceful way to take a node out for maintenance or a scale-down. Still a capacity change: the cluster loses that host's cores, and running tasks on it are rescheduled elsewhere. Needs spark.decommission.enabled and an allowed value of spark.master.ui.decommission.allow.mode; both are off or restrictive by default.","description":"Decommission every standalone worker on one host. Spark stops scheduling new tasks there and migrates shuffle and cached blocks off before the executors go away, which is the graceful way to take a node out for maintenance or a scale-down. Still a capacity change: the cluster loses that host's cores, and running tasks on it are rescheduled elsewhere. Needs spark.decommission.enabled and an allowed value of spark.master.ui.decommission.allow.mode; both are off or restrictive by default.","kind":"script","risk":"high","side_effects":["Stops scheduling new tasks on every worker on the host.","Migrates shuffle and cached blocks off the host, then removes its executors.","Tasks running on the host are rescheduled onto the remaining workers.","The cluster permanently loses that host's capacity until the worker is restarted."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or address of the worker host, as reported by spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,253}$","max_length":253}}],"examples":[{"title":"Drain a node before maintenance","args":{"host":"spark-worker-3.internal"}}],"search_terms":["decommission worker","drain spark node","scale down cluster","node maintenance"]},{"id":"spark.sql_execution","title":"GET .../sql/{execution_id}","summary":"Show one Spark SQL execution with its node-level metrics — rows produced, bytes read, shuffle sizes, and time per operator — and optionally the physical plan. This is where a query's cost is attributed: the node with the row explosion or the full scan is named here.","description":"Show one Spark SQL execution with its node-level metrics — rows produced, bytes read, shuffle sizes, and time per operator — and optionally the physical plan. This is where a query's cost is attributed: the node with the row explosion or the full scan is named here.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","The plan and node descriptions include table, column, and literal values from the query."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"execution_id","type":"integer","required":true,"description":"SQL execution id, from spark.sql_executions.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"plan_description","type":"string","required":false,"default":"true","description":"Include the physical plan text.","validation":{"enum":["true","false"]}}],"examples":[{"title":"The plan and metrics for one query","args":{"app_id":"app-20260805120000-0001","execution_id":12}}],"search_terms":["query plan","physical plan","why is the query slow","full table scan","broadcast join"]},{"id":"spark.sql_executions","title":"List SQL executions (GET .../sql)","summary":"List an application's Spark SQL executions with their description, submission time, duration, and the jobs each one spawned. For a SQL or DataFrame workload this is the layer that maps a slow query to the jobs and stages underneath it.","description":"List an application's Spark SQL executions with their description, submission time, duration, and the jobs each one spawned. For a SQL or DataFrame workload this is the layer that maps a slow query to the jobs and stages underneath it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","Execution descriptions come from the submitted query and can include table and column names."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset within the application's executions.","validation":{"min":0,"max":1000000}},{"name":"length","type":"integer","required":false,"default":25,"description":"Executions returned in this page.","validation":{"min":1,"max":100}},{"name":"plan_description","type":"string","required":false,"default":"false","description":"Include the physical plan text for every execution. Off by default — a plan is large, and spark.sql_execution returns one on demand.","validation":{"enum":["true","false"]}}],"examples":[{"title":"SQL executions in an application","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark sql","slow query","dataframe execution","query duration"]},{"id":"spark.stage","title":"GET /api/v1/applications/{app_id}/stages/{stage_id}","summary":"Show every attempt of one stage with its status, task counts, timing, shuffle and spill metrics, and — with with_summaries — the task metric quantiles. A stage with more than one attempt has been retried, which usually means lost executors or a fetch failure.","description":"Show every attempt of one stage with its status, task counts, timing, shuffle and spill metrics, and — with with_summaries — the task metric quantiles. A stage with more than one attempt has been retried, which usually means lost executors or a fetch failure.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages or a job's stageIds.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"details","type":"string","required":false,"default":"false","description":"Include the per-task detail. Off by default — a wide stage has thousands of tasks.","validation":{"enum":["true","false"]}},{"name":"with_summaries","type":"string","required":false,"default":"false","description":"Include task and executor metric quantile summaries for the stage.","validation":{"enum":["true","false"]}}],"examples":[{"title":"One stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"One stage with its metric quantiles","args":{"app_id":"app-20260805120000-0001","stage_id":4,"with_summaries":"true"}}],"search_terms":["stage detail","stage retry","stage attempts","fetch failure"]},{"id":"spark.stage_kill","title":"Kill a running Spark stage (POST /stages/stage/kill on the driver UI)","summary":"Kill one running stage in the application on the live driver UI. Narrower than killing the job: the stage's tasks are cancelled, and whether the job survives depends on whether Spark can retry the stage. Use it to shed one runaway stage — a skewed shuffle, a stage stuck on a dead host — without losing the whole job. The action reads the stage back and returns its attempts. Needs spark.ui.killEnabled, which is on by default.","description":"Kill one running stage in the application on the live driver UI. Narrower than killing the job: the stage's tasks are cancelled, and whether the job survives depends on whether Spark can retry the stage. Use it to shed one runaway stage — a skewed shuffle, a stage stuck on a dead host — without losing the whole job. The action reads the stage back and returns its attempts. Needs spark.ui.killEnabled, which is on by default.","kind":"script","risk":"high","side_effects":["Cancels the running tasks in the stage.","The owning job fails unless Spark retries the stage successfully.","Partial shuffle output the stage wrote is discarded.","Whether the stage was running is reported by reading it back, not assumed."],"args":[{"name":"stage_id","type":"integer","required":true,"description":"Stage id to kill, from spark.stages with source driver.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Kill a stage stuck on one partition","args":{"stage_id":7}}],"search_terms":["kill spark stage","cancel stage","stuck stage","skewed shuffle"]},{"id":"spark.stage_task_summary","title":"Get task metric quantiles for a stage attempt (GET .../taskSummary)","summary":"Get the task metric quantiles for one stage attempt — duration, GC time, shuffle read and write, input bytes, and memory and disk spill at each quantile. This is the skew read: when the maximum task duration dwarfs the median, the stage is waiting on a few partitions, not on the cluster.","description":"Get the task metric quantiles for one stage attempt — duration, GC time, shuffle read and write, input bytes, and memory and disk spill at each quantile. This is the skew read: when the maximum task duration dwarfs the median, the stage is waiting on a few partitions, not on the cluster.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages.","validation":{"min":0,"max":1000000}},{"name":"attempt_id","type":"integer","required":false,"default":0,"description":"Stage attempt. 0 is the first attempt; spark.stage lists the rest.","validation":{"min":0,"max":1000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"quantiles","type":"string","required":false,"default":"0.05,0.25,0.5,0.75,0.95","description":"Comma-separated quantiles between 0 and 1.","validation":{"pattern":"^[0-9.]{1,4}(,[0-9.]{1,4}){0,9}$","max_length":50}}],"examples":[{"title":"Where the time went in a stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"The long tail only","args":{"app_id":"app-20260805120000-0001","quantiles":"0.5,0.9,0.99,1.0","stage_id":4}}],"search_terms":["data skew","straggler task","task quantiles","p99 task duration","gc time"]},{"id":"spark.stage_tasks","title":"List tasks in a stage attempt (GET .../taskList)","summary":"List individual tasks in one stage attempt with their executor, host, duration, status, and — for a failed task — the error message. Sort by `-runtime` to put the slowest first, or filter `status: failed` to read why the stage broke.","description":"List individual tasks in one stage attempt with their executor, host, duration, status, and — for a failed task — the error message. Sort by `-runtime` to put the slowest first, or filter `status: failed` to read why the stage broke.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","A failed task's error message is returned as Spark recorded it."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages.","validation":{"min":0,"max":1000000}},{"name":"attempt_id","type":"integer","required":false,"default":0,"description":"Stage attempt. 0 is the first attempt.","validation":{"min":0,"max":1000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to tasks in this state. Empty returns every task in the page.","validation":{"enum":["","running","success","killed","failed","pending"]}},{"name":"sort_by","type":"string","required":false,"default":"-runtime","description":"Sort order for the page. Slowest first by default.","validation":{"enum":["-runtime","runtime","-executorRunTime","executorRunTime","-launchTime","launchTime"]}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset within the stage's tasks.","validation":{"min":0,"max":1000000}},{"name":"length","type":"integer","required":false,"default":25,"description":"Tasks returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"The slowest tasks in a stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"Only the failures","args":{"app_id":"app-20260805120000-0001","stage_id":4,"status":"failed"}}],"search_terms":["failed tasks","slowest task","task error message","which executor"]},{"id":"spark.stages","title":"List an application's stages (GET /api/v1/applications/{app_id}/stages)","summary":"List a Spark application's stages with status, task counts, duration, shuffle read and write bytes, spill, and input and output sizes. This is where a slow job is diagnosed: the stage with the outsized shuffle read or spill is usually the one to look at.","description":"List a Spark application's stages with status, task counts, duration, shuffle read and write bytes, spill, and input and output sizes. This is where a slow job is diagnosed: the stage with the outsized shuffle read or spill is usually the one to look at.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to stages in this state. Empty returns every stage.","validation":{"enum":["","active","complete","pending","failed","skipped"]}},{"name":"details","type":"string","required":false,"default":"false","description":"Include the per-task detail for every stage. Off by default — on a large application it turns a summary into megabytes.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Every stage in an application","args":{"app_id":"app-20260805120000-0001"}},{"title":"The stages still running on a live driver","args":{"app_id":"app-20260805120000-0001","source":"driver","status":"active"}}],"search_terms":["spark stages","shuffle read","spill to disk","slow stage","failed stage"]},{"id":"spark.storage_rdds","title":"List cached RDDs (GET .../storage/rdd)","summary":"List the RDDs and DataFrames an application has cached, with their storage level, partition count, and how many bytes sit in memory versus spilled to disk. Read it when executors are short on memory: a large cache that is mostly on disk is paying the cost of caching without the benefit.","description":"List the RDDs and DataFrames an application has cached, with their storage level, partition count, and how many bytes sit in memory versus spilled to disk. Read it when executors are short on memory: a large cache that is mostly on disk is paying the cost of caching without the benefit.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"driver","description":"Which UI to ask. Storage is live state, so a driver ($SPARK_UI_URL) is the default; the history server reports what was cached when the event log was written.","validation":{"enum":["history","driver"]}}],"examples":[{"title":"What this application has cached","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["cached rdd","persist","memory used","spilled to disk","storage level"]},{"id":"spark.submission_kill","title":"Kill a REST submission (POST /v1/submissions/kill/{id})","summary":"Kill one cluster-mode submission through the standalone REST submission server. The driver and its application are terminated, and the server answers with whether it found and killed the submission. This is the path for a job submitted with `spark-submit --deploy-mode cluster` when you have the submission id but not the master UI. Needs spark.master.rest.enabled, which is off by default.","description":"Kill one cluster-mode submission through the standalone REST submission server. The driver and its application are terminated, and the server answers with whether it found and killed the submission. This is the path for a job submitted with `spark-submit --deploy-mode cluster` when you have the submission id but not the master UI. Needs spark.master.rest.enabled, which is off by default.","kind":"script","risk":"high","side_effects":["Terminates the submitted driver and the application it is running.","In-flight work is lost; whatever was already written stays written.","The server reports whether the submission was found and killed."],"args":[{"name":"submission_id","type":"string","required":true,"description":"Submission id to kill, e.g. driver-20260805120000-0003.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a submitted job by id","args":{"submission_id":"driver-20260805120000-0003"}}],"search_terms":["kill submission","cancel spark-submit","stop cluster mode driver"]},{"id":"spark.submission_status","title":"Get a REST submission's status (GET /v1/submissions/status/{id})","summary":"Get the state of one cluster-mode submission from the standalone REST submission server — whether the driver is queued, running, finished, or failed, and the worker it landed on. Use it to follow a `spark-submit --deploy-mode cluster` job whose client already exited. Needs spark.master.rest.enabled, which is off by default.","description":"Get the state of one cluster-mode submission from the standalone REST submission server — whether the driver is queued, running, finished, or failed, and the worker it landed on. Use it to follow a `spark-submit --deploy-mode cluster` job whose client already exited. Needs spark.master.rest.enabled, which is off by default.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the standalone REST submission server.","Read-only — never writes or mutates data."],"args":[{"name":"submission_id","type":"string","required":true,"description":"Submission id, e.g. driver-20260805120000-0003, as returned when the job was submitted.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Where a cluster-mode driver got to","args":{"submission_id":"driver-20260805120000-0003"}}],"search_terms":["submission status","driver state","cluster deploy mode","spark-submit status"]},{"id":"spark.version","title":"GET /api/v1/version","summary":"Show the Spark version a UI is running. Use it to confirm a driver or history server is reachable and which release it is on before reading a version-specific field.","description":"Show the Spark version a UI is running. Use it to confirm a driver or history server is reachable and which release it is on before reading a version-specific field.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"History server version","args":{}},{"title":"Live driver version","args":{"source":"driver"}}],"search_terms":["spark version","which release"]}],"previous_versions":[{"version":"0.1.2","content_hash":"sha256:66245ab9256a75438b4f5d9f3d98e190da6c224fdd4b643b909bc31e2671e352","tarball_url":"https://registry.emisar.dev/v1/packs/spark/0.1.2/66245ab9256a75438b4f5d9f3d98e190da6c224fdd4b643b909bc31e2671e352/pack.tar.gz","actions":[{"id":"spark.application","title":"GET /api/v1/applications/{app_id}","summary":"Show one Spark application — its name, user, and every attempt with start time, end time, duration, and whether it completed. Read it to confirm an application id and see whether the run you care about finished or is still going.","description":"Show one Spark application — its name, user, and every attempt with start time, end time, duration, and whether it completed. Read it to confirm an application id and see whether the run you care about finished or is still going.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, e.g. app-20260805120000-0001 or application_1754_0007.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"One application from the history server","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark application detail","app duration","did the app finish"]},{"id":"spark.applications","title":"List Spark applications (GET /api/v1/applications)","summary":"List Spark applications with their id, name, user, start and end times, and attempts. Against the history server this is the record of what ran; against a live driver it returns the one application that driver is running. Every other action in this pack takes the app_id this returns.","description":"List Spark applications with their id, name, user, start and end times, and attempts. Against the history server this is the record of what ran; against a live driver it returns the one application that driver is running. Every other action in this pack takes the app_id this returns.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to applications that are still running or have completed. Empty returns both. On the history server, running means an application whose event log is still open.","validation":{"enum":["","running","completed"]}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Applications returned.","validation":{"min":1,"max":200}},{"name":"min_date","type":"string","required":false,"default":"","description":"Only applications that started at or after this date, e.g. 2026-08-05 or 2026-08-05T00:00:00.000GMT.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,3})?(GMT|Z)?)?)?$","max_length":32}}],"examples":[{"title":"Recent applications from the history server","args":{}},{"title":"The application running on this driver","args":{"source":"driver"}},{"title":"Applications still in flight","args":{"status":"running"}}],"search_terms":["list spark applications","which app is running","spark app id","completed applications"]},{"id":"spark.environment","title":"Dump an application's Spark configuration (GET .../environment)","summary":"Dump the Spark configuration an application is running with, plus its runtime versions and resource profiles.","description":"Dump the Spark configuration an application is running with, plus its runtime versions and resource profiles. Answers \"what settings did this job actually get\" when a tuning change did not take effect. High risk because it is a configuration dump: Spark's own spark.redaction.regex masks the property values it recognizes, and the JVM system properties and classpath are dropped on the runner host, but an object-store key or keystore password stored under a property name that pattern does not match is returned as configured.","kind":"script","risk":"high","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","Returns Spark configuration properties, which can carry credentials the redaction pattern does not match.","JVM system properties and the classpath are removed on the runner host."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"The configuration one application ran with","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark config","which settings","spark.sql.shuffle.partitions","executor memory setting","runtime versions"]},{"id":"spark.executor_threads","title":"Dump an executor's threads (GET .../executors/{executor_id}/threads)","summary":"Dump the stack traces of every thread in one live executor. This is the read for a task that is running but making no progress — the stack says whether it is blocked on a lock, waiting on a shuffle fetch, or spinning in user code. Only a live driver serves it; the history server does not. Heavier than the other reads: collecting the dump briefly pauses the executor's threads.","description":"Dump the stack traces of every thread in one live executor. This is the read for a task that is running but making no progress — the stack says whether it is blocked on a lock, waiting on a shuffle fetch, or spinning in user code. Only a live driver serves it; the history server does not. Heavier than the other reads: collecting the dump briefly pauses the executor's threads.","kind":"script","risk":"medium","side_effects":["One HTTP GET to the live driver, which asks the executor for a thread dump.","Read-only — no application, job, or executor state is changed.","Briefly pauses the executor's threads while stacks are collected.","Returns no application data — stack frames only."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications with source driver.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"executor_id","type":"string","required":true,"description":"Executor id, from spark.executors. \"driver\" dumps the driver's own threads.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Why executor 1 is not progressing","args":{"app_id":"app-20260805120000-0001","executor_id":"1"}},{"title":"The driver's own threads","args":{"app_id":"app-20260805120000-0001","executor_id":"driver"}}],"search_terms":["thread dump","stuck task","deadlock","executor hung","no progress"]},{"id":"spark.executors","title":"List an application's executors (GET .../executors)","summary":"List an application's executors with cores, active and completed tasks, failed tasks, GC time, storage memory used against total, disk used, and their host and log URLs. Read it when an application is slow or losing work: a single executor with most of the failed tasks names the bad host.","description":"List an application's executors with cores, active and completed tasks, failed tasks, GC time, storage memory used against total, disk used, and their host and log URLs. Read it when an application is slow or losing work: a single executor with most of the failed tasks names the bad host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"include_removed","type":"string","required":false,"default":"false","description":"Include executors that have already been removed (the allexecutors endpoint). That is what shows an executor lost mid-run, which the active list no longer mentions.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Active executors","args":{"app_id":"app-20260805120000-0001"}},{"title":"Including executors that were lost","args":{"app_id":"app-20260805120000-0001","include_removed":"true"}}],"search_terms":["spark executors","executor memory","lost executor","gc time","executor failures"]},{"id":"spark.job","title":"GET /api/v1/applications/{app_id}/jobs/{job_id}","summary":"Show one Spark job — status, timing, the stage ids it owns, and its task counts including failed and killed. Read it after spark.jobs narrows to the job you care about, then follow its stage ids into spark.stage.","description":"Show one Spark job — status, timing, the stage ids it owns, and its task counts including failed and killed. Read it after spark.jobs narrows to the job you care about, then follow its stage ids into spark.stage.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"job_id","type":"integer","required":true,"description":"Job id, from spark.jobs.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"One job","args":{"app_id":"app-20260805120000-0001","job_id":3}}],"search_terms":["spark job detail","job stages","job failure reason"]},{"id":"spark.job_kill","title":"Kill a running Spark job (POST /jobs/job/kill on the driver UI)","summary":"Kill one running job in the application on the live driver UI. Every task in the job is cancelled and the job is marked failed; whatever the job had already written stays written, so a partially completed output is the normal outcome. The action reads the job back afterwards and returns its state, so a request against an already-finished job is visible rather than assumed. Needs spark.ui.killEnabled, which is on by default.","description":"Kill one running job in the application on the live driver UI. Every task in the job is cancelled and the job is marked failed; whatever the job had already written stays written, so a partially completed output is the normal outcome. The action reads the job back afterwards and returns its state, so a request against an already-finished job is visible rather than assumed. Needs spark.ui.killEnabled, which is on by default.","kind":"script","risk":"high","side_effects":["Cancels every running task in the job; the job ends as failed.","Partial output the job already wrote is left in place.","The application keeps running; only this job is cancelled.","Whether the job was running is reported by reading it back, not assumed."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job id to kill, from spark.jobs with source driver.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Kill a job that will never finish","args":{"job_id":12}}],"search_terms":["kill spark job","cancel job","stop runaway job","runaway query"]},{"id":"spark.jobs","title":"List an application's jobs (GET /api/v1/applications/{app_id}/jobs)","summary":"List a Spark application's jobs with their status, submission time, duration, and task counts — completed, active, skipped, and failed. Filter by `status: failed` to find the job that broke, or `status: running` to see what a stuck application is still working on.","description":"List a Spark application's jobs with their status, submission time, duration, and task counts — completed, active, skipped, and failed. Filter by `status: failed` to find the job that broke, or `status: running` to see what a stuck application is still working on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to jobs in this state. Empty returns every job.","validation":{"enum":["","running","succeeded","failed","unknown"]}}],"examples":[{"title":"Every job in an application","args":{"app_id":"app-20260805120000-0001"}},{"title":"The failed jobs of a live application","args":{"app_id":"app-20260805120000-0001","source":"driver","status":"failed"}}],"search_terms":["spark jobs","failed job","running job","what is the app doing"]},{"id":"spark.master_app_kill","title":"Kill an application from the standalone master (POST /app/kill)","summary":"Kill one whole application on a Spark standalone master. Its driver and every executor are terminated and its cores and memory return to the cluster — which is the point when one application is starving everything else — but the application's work stops wherever it was, so partial output stays partial. The action reads the master's state back and reports whether the application is still active.","description":"Kill one whole application on a Spark standalone master. Its driver and every executor are terminated and its cores and memory return to the cluster — which is the point when one application is starving everything else — but the application's work stops wherever it was, so partial output stays partial. The action reads the master's state back and reports whether the application is still active.","kind":"script","risk":"high","side_effects":["Terminates the application's driver and every one of its executors.","In-flight work is lost; whatever was already written stays written.","Frees the application's cores and memory for other applications.","Whether the application ended is reported by reading the master back, not assumed."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id to kill, e.g. app-20260805120000-0001, from spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill the application that is holding every core","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["kill spark application","free up cores","stop the app","application starving the cluster"]},{"id":"spark.master_driver_kill","title":"Kill a cluster-mode driver from the standalone master (POST /driver/kill)","summary":"Kill one cluster-mode driver on a Spark standalone master. The driver process and the application it runs are terminated. Use it for a submitted job whose client is long gone — a driver stuck in a retry loop, or one submitted by mistake. The action reads the master's state back and reports whether the driver is still active.","description":"Kill one cluster-mode driver on a Spark standalone master. The driver process and the application it runs are terminated. Use it for a submitted job whose client is long gone — a driver stuck in a retry loop, or one submitted by mistake. The action reads the master's state back and reports whether the driver is still active.","kind":"script","risk":"high","side_effects":["Terminates the driver process and the application it is running.","In-flight work is lost; whatever was already written stays written.","A driver submitted with supervise is not restarted after an explicit kill.","Whether the driver ended is reported by reading the master back, not assumed."],"args":[{"name":"driver_id","type":"string","required":true,"description":"Driver id to kill, e.g. driver-20260805120000-0003, from spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a driver stuck restarting","args":{"driver_id":"driver-20260805120000-0003"}}],"search_terms":["kill spark driver","stop cluster mode job","driver retry loop"]},{"id":"spark.master_state","title":"Show standalone cluster state (GET /json/ on the master)","summary":"Show a Spark standalone master's cluster state — every worker with its state, cores and memory used against total, the running and completed applications with the resources each holds, and any submitted drivers. This is the capacity read: an application stuck in WAITING with no free cores means the cluster is full, not that the application is broken.","description":"Show a Spark standalone master's cluster state — every worker with its state, cores and memory used against total, the running and completed applications with the resources each holds, and any submitted drivers. This is the capacity read: an application stuck in WAITING with no free cores means the cluster is full, not that the application is broken.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the standalone master's web UI.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Cluster capacity and what is using it","args":{}}],"search_terms":["spark cluster state","workers alive","free cores","app waiting","standalone master"]},{"id":"spark.master_worker_decommission","title":"Decommission a standalone worker host (POST /workers/kill on the master)","summary":"Decommission every standalone worker on one host. Spark stops scheduling new tasks there and migrates shuffle and cached blocks off before the executors go away, which is the graceful way to take a node out for maintenance or a scale-down. Still a capacity change: the cluster loses that host's cores, and running tasks on it are rescheduled elsewhere. Needs spark.decommission.enabled and an allowed value of spark.master.ui.decommission.allow.mode; both are off or restrictive by default.","description":"Decommission every standalone worker on one host. Spark stops scheduling new tasks there and migrates shuffle and cached blocks off before the executors go away, which is the graceful way to take a node out for maintenance or a scale-down. Still a capacity change: the cluster loses that host's cores, and running tasks on it are rescheduled elsewhere. Needs spark.decommission.enabled and an allowed value of spark.master.ui.decommission.allow.mode; both are off or restrictive by default.","kind":"script","risk":"high","side_effects":["Stops scheduling new tasks on every worker on the host.","Migrates shuffle and cached blocks off the host, then removes its executors.","Tasks running on the host are rescheduled onto the remaining workers.","The cluster permanently loses that host's capacity until the worker is restarted."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or address of the worker host, as reported by spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,253}$","max_length":253}}],"examples":[{"title":"Drain a node before maintenance","args":{"host":"spark-worker-3.internal"}}],"search_terms":["decommission worker","drain spark node","scale down cluster","node maintenance"]},{"id":"spark.sql_execution","title":"GET .../sql/{execution_id}","summary":"Show one Spark SQL execution with its node-level metrics — rows produced, bytes read, shuffle sizes, and time per operator — and optionally the physical plan. This is where a query's cost is attributed: the node with the row explosion or the full scan is named here.","description":"Show one Spark SQL execution with its node-level metrics — rows produced, bytes read, shuffle sizes, and time per operator — and optionally the physical plan. This is where a query's cost is attributed: the node with the row explosion or the full scan is named here.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","The plan and node descriptions include table, column, and literal values from the query."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"execution_id","type":"integer","required":true,"description":"SQL execution id, from spark.sql_executions.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"plan_description","type":"string","required":false,"default":"true","description":"Include the physical plan text.","validation":{"enum":["true","false"]}}],"examples":[{"title":"The plan and metrics for one query","args":{"app_id":"app-20260805120000-0001","execution_id":12}}],"search_terms":["query plan","physical plan","why is the query slow","full table scan","broadcast join"]},{"id":"spark.sql_executions","title":"List SQL executions (GET .../sql)","summary":"List an application's Spark SQL executions with their description, submission time, duration, and the jobs each one spawned. For a SQL or DataFrame workload this is the layer that maps a slow query to the jobs and stages underneath it.","description":"List an application's Spark SQL executions with their description, submission time, duration, and the jobs each one spawned. For a SQL or DataFrame workload this is the layer that maps a slow query to the jobs and stages underneath it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","Execution descriptions come from the submitted query and can include table and column names."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset within the application's executions.","validation":{"min":0,"max":1000000}},{"name":"length","type":"integer","required":false,"default":25,"description":"Executions returned in this page.","validation":{"min":1,"max":100}},{"name":"plan_description","type":"string","required":false,"default":"false","description":"Include the physical plan text for every execution. Off by default — a plan is large, and spark.sql_execution returns one on demand.","validation":{"enum":["true","false"]}}],"examples":[{"title":"SQL executions in an application","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark sql","slow query","dataframe execution","query duration"]},{"id":"spark.stage","title":"GET /api/v1/applications/{app_id}/stages/{stage_id}","summary":"Show every attempt of one stage with its status, task counts, timing, shuffle and spill metrics, and — with with_summaries — the task metric quantiles. A stage with more than one attempt has been retried, which usually means lost executors or a fetch failure.","description":"Show every attempt of one stage with its status, task counts, timing, shuffle and spill metrics, and — with with_summaries — the task metric quantiles. A stage with more than one attempt has been retried, which usually means lost executors or a fetch failure.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages or a job's stageIds.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"details","type":"string","required":false,"default":"false","description":"Include the per-task detail. Off by default — a wide stage has thousands of tasks.","validation":{"enum":["true","false"]}},{"name":"with_summaries","type":"string","required":false,"default":"false","description":"Include task and executor metric quantile summaries for the stage.","validation":{"enum":["true","false"]}}],"examples":[{"title":"One stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"One stage with its metric quantiles","args":{"app_id":"app-20260805120000-0001","stage_id":4,"with_summaries":"true"}}],"search_terms":["stage detail","stage retry","stage attempts","fetch failure"]},{"id":"spark.stage_kill","title":"Kill a running Spark stage (POST /stages/stage/kill on the driver UI)","summary":"Kill one running stage in the application on the live driver UI. Narrower than killing the job: the stage's tasks are cancelled, and whether the job survives depends on whether Spark can retry the stage. Use it to shed one runaway stage — a skewed shuffle, a stage stuck on a dead host — without losing the whole job. The action reads the stage back and returns its attempts. Needs spark.ui.killEnabled, which is on by default.","description":"Kill one running stage in the application on the live driver UI. Narrower than killing the job: the stage's tasks are cancelled, and whether the job survives depends on whether Spark can retry the stage. Use it to shed one runaway stage — a skewed shuffle, a stage stuck on a dead host — without losing the whole job. The action reads the stage back and returns its attempts. Needs spark.ui.killEnabled, which is on by default.","kind":"script","risk":"high","side_effects":["Cancels the running tasks in the stage.","The owning job fails unless Spark retries the stage successfully.","Partial shuffle output the stage wrote is discarded.","Whether the stage was running is reported by reading it back, not assumed."],"args":[{"name":"stage_id","type":"integer","required":true,"description":"Stage id to kill, from spark.stages with source driver.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Kill a stage stuck on one partition","args":{"stage_id":7}}],"search_terms":["kill spark stage","cancel stage","stuck stage","skewed shuffle"]},{"id":"spark.stage_task_summary","title":"Get task metric quantiles for a stage attempt (GET .../taskSummary)","summary":"Get the task metric quantiles for one stage attempt — duration, GC time, shuffle read and write, input bytes, and memory and disk spill at each quantile. This is the skew read: when the maximum task duration dwarfs the median, the stage is waiting on a few partitions, not on the cluster.","description":"Get the task metric quantiles for one stage attempt — duration, GC time, shuffle read and write, input bytes, and memory and disk spill at each quantile. This is the skew read: when the maximum task duration dwarfs the median, the stage is waiting on a few partitions, not on the cluster.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages.","validation":{"min":0,"max":1000000}},{"name":"attempt_id","type":"integer","required":false,"default":0,"description":"Stage attempt. 0 is the first attempt; spark.stage lists the rest.","validation":{"min":0,"max":1000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"quantiles","type":"string","required":false,"default":"0.05,0.25,0.5,0.75,0.95","description":"Comma-separated quantiles between 0 and 1.","validation":{"pattern":"^[0-9.]{1,4}(,[0-9.]{1,4}){0,9}$","max_length":50}}],"examples":[{"title":"Where the time went in a stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"The long tail only","args":{"app_id":"app-20260805120000-0001","quantiles":"0.5,0.9,0.99,1.0","stage_id":4}}],"search_terms":["data skew","straggler task","task quantiles","p99 task duration","gc time"]},{"id":"spark.stage_tasks","title":"List tasks in a stage attempt (GET .../taskList)","summary":"List individual tasks in one stage attempt with their executor, host, duration, status, and — for a failed task — the error message. Sort by `-runtime` to put the slowest first, or filter `status: failed` to read why the stage broke.","description":"List individual tasks in one stage attempt with their executor, host, duration, status, and — for a failed task — the error message. Sort by `-runtime` to put the slowest first, or filter `status: failed` to read why the stage broke.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","A failed task's error message is returned as Spark recorded it."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages.","validation":{"min":0,"max":1000000}},{"name":"attempt_id","type":"integer","required":false,"default":0,"description":"Stage attempt. 0 is the first attempt.","validation":{"min":0,"max":1000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to tasks in this state. Empty returns every task in the page.","validation":{"enum":["","running","success","killed","failed","pending"]}},{"name":"sort_by","type":"string","required":false,"default":"-runtime","description":"Sort order for the page. Slowest first by default.","validation":{"enum":["-runtime","runtime","-executorRunTime","executorRunTime","-launchTime","launchTime"]}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset within the stage's tasks.","validation":{"min":0,"max":1000000}},{"name":"length","type":"integer","required":false,"default":25,"description":"Tasks returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"The slowest tasks in a stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"Only the failures","args":{"app_id":"app-20260805120000-0001","stage_id":4,"status":"failed"}}],"search_terms":["failed tasks","slowest task","task error message","which executor"]},{"id":"spark.stages","title":"List an application's stages (GET /api/v1/applications/{app_id}/stages)","summary":"List a Spark application's stages with status, task counts, duration, shuffle read and write bytes, spill, and input and output sizes. This is where a slow job is diagnosed: the stage with the outsized shuffle read or spill is usually the one to look at.","description":"List a Spark application's stages with status, task counts, duration, shuffle read and write bytes, spill, and input and output sizes. This is where a slow job is diagnosed: the stage with the outsized shuffle read or spill is usually the one to look at.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to stages in this state. Empty returns every stage.","validation":{"enum":["","active","complete","pending","failed","skipped"]}},{"name":"details","type":"string","required":false,"default":"false","description":"Include the per-task detail for every stage. Off by default — on a large application it turns a summary into megabytes.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Every stage in an application","args":{"app_id":"app-20260805120000-0001"}},{"title":"The stages still running on a live driver","args":{"app_id":"app-20260805120000-0001","source":"driver","status":"active"}}],"search_terms":["spark stages","shuffle read","spill to disk","slow stage","failed stage"]},{"id":"spark.storage_rdds","title":"List cached RDDs (GET .../storage/rdd)","summary":"List the RDDs and DataFrames an application has cached, with their storage level, partition count, and how many bytes sit in memory versus spilled to disk. Read it when executors are short on memory: a large cache that is mostly on disk is paying the cost of caching without the benefit.","description":"List the RDDs and DataFrames an application has cached, with their storage level, partition count, and how many bytes sit in memory versus spilled to disk. Read it when executors are short on memory: a large cache that is mostly on disk is paying the cost of caching without the benefit.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"driver","description":"Which UI to ask. Storage is live state, so a driver ($SPARK_UI_URL) is the default; the history server reports what was cached when the event log was written.","validation":{"enum":["history","driver"]}}],"examples":[{"title":"What this application has cached","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["cached rdd","persist","memory used","spilled to disk","storage level"]},{"id":"spark.submission_kill","title":"Kill a REST submission (POST /v1/submissions/kill/{id})","summary":"Kill one cluster-mode submission through the standalone REST submission server. The driver and its application are terminated, and the server answers with whether it found and killed the submission. This is the path for a job submitted with `spark-submit --deploy-mode cluster` when you have the submission id but not the master UI. Needs spark.master.rest.enabled, which is off by default.","description":"Kill one cluster-mode submission through the standalone REST submission server. The driver and its application are terminated, and the server answers with whether it found and killed the submission. This is the path for a job submitted with `spark-submit --deploy-mode cluster` when you have the submission id but not the master UI. Needs spark.master.rest.enabled, which is off by default.","kind":"script","risk":"high","side_effects":["Terminates the submitted driver and the application it is running.","In-flight work is lost; whatever was already written stays written.","The server reports whether the submission was found and killed."],"args":[{"name":"submission_id","type":"string","required":true,"description":"Submission id to kill, e.g. driver-20260805120000-0003.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a submitted job by id","args":{"submission_id":"driver-20260805120000-0003"}}],"search_terms":["kill submission","cancel spark-submit","stop cluster mode driver"]},{"id":"spark.submission_status","title":"Get a REST submission's status (GET /v1/submissions/status/{id})","summary":"Get the state of one cluster-mode submission from the standalone REST submission server — whether the driver is queued, running, finished, or failed, and the worker it landed on. Use it to follow a `spark-submit --deploy-mode cluster` job whose client already exited. Needs spark.master.rest.enabled, which is off by default.","description":"Get the state of one cluster-mode submission from the standalone REST submission server — whether the driver is queued, running, finished, or failed, and the worker it landed on. Use it to follow a `spark-submit --deploy-mode cluster` job whose client already exited. Needs spark.master.rest.enabled, which is off by default.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the standalone REST submission server.","Read-only — never writes or mutates data."],"args":[{"name":"submission_id","type":"string","required":true,"description":"Submission id, e.g. driver-20260805120000-0003, as returned when the job was submitted.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Where a cluster-mode driver got to","args":{"submission_id":"driver-20260805120000-0003"}}],"search_terms":["submission status","driver state","cluster deploy mode","spark-submit status"]},{"id":"spark.version","title":"GET /api/v1/version","summary":"Show the Spark version a UI is running. Use it to confirm a driver or history server is reachable and which release it is on before reading a version-specific field.","description":"Show the Spark version a UI is running. Use it to confirm a driver or history server is reachable and which release it is on before reading a version-specific field.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"History server version","args":{}},{"title":"Live driver version","args":{"source":"driver"}}],"search_terms":["spark version","which release"]}]},{"version":"0.1.0","content_hash":"sha256:6b24467c62bd6eff06d69bd43e470ad27722a3ffd78367ea33ebaf54b0f4334b","tarball_url":"https://registry.emisar.dev/v1/packs/spark/0.1.0/6b24467c62bd6eff06d69bd43e470ad27722a3ffd78367ea33ebaf54b0f4334b/pack.tar.gz","actions":[{"id":"spark.application","title":"GET /api/v1/applications/{app_id}","summary":"Show one Spark application — its name, user, and every attempt with start time, end time, duration, and whether it completed. Read it to confirm an application id and see whether the run you care about finished or is still going.","description":"Show one Spark application — its name, user, and every attempt with start time, end time, duration, and whether it completed. Read it to confirm an application id and see whether the run you care about finished or is still going.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, e.g. app-20260805120000-0001 or application_1754_0007.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"One application from the history server","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark application detail","app duration","did the app finish"]},{"id":"spark.applications","title":"List Spark applications (GET /api/v1/applications)","summary":"List Spark applications with their id, name, user, start and end times, and attempts. Against the history server this is the record of what ran; against a live driver it returns the one application that driver is running. Every other action in this pack takes the app_id this returns.","description":"List Spark applications with their id, name, user, start and end times, and attempts. Against the history server this is the record of what ran; against a live driver it returns the one application that driver is running. Every other action in this pack takes the app_id this returns.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to applications that are still running or have completed. Empty returns both. On the history server, running means an application whose event log is still open.","validation":{"enum":["","running","completed"]}},{"name":"limit","type":"integer","required":false,"default":25,"description":"Applications returned.","validation":{"min":1,"max":200}},{"name":"min_date","type":"string","required":false,"default":"","description":"Only applications that started at or after this date, e.g. 2026-08-05 or 2026-08-05T00:00:00.000GMT.","validation":{"pattern":"^([0-9]{4}-[0-9]{2}-[0-9]{2}(T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]{1,3})?(GMT|Z)?)?)?$","max_length":32}}],"examples":[{"title":"Recent applications from the history server","args":{}},{"title":"The application running on this driver","args":{"source":"driver"}},{"title":"Applications still in flight","args":{"status":"running"}}],"search_terms":["list spark applications","which app is running","spark app id","completed applications"]},{"id":"spark.environment","title":"Dump an application's Spark configuration (GET .../environment)","summary":"Dump the Spark configuration an application is running with, plus its runtime versions and resource profiles.","description":"Dump the Spark configuration an application is running with, plus its runtime versions and resource profiles. Answers \"what settings did this job actually get\" when a tuning change did not take effect. High risk because it is a configuration dump: Spark's own spark.redaction.regex masks the property values it recognizes, and the JVM system properties and classpath are dropped on the runner host, but an object-store key or keystore password stored under a property name that pattern does not match is returned as configured.","kind":"script","risk":"high","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","Returns Spark configuration properties, which can carry credentials the redaction pattern does not match.","JVM system properties and the classpath are removed on the runner host."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"The configuration one application ran with","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark config","which settings","spark.sql.shuffle.partitions","executor memory setting","runtime versions"]},{"id":"spark.executor_threads","title":"Dump an executor's threads (GET .../executors/{executor_id}/threads)","summary":"Dump the stack traces of every thread in one live executor. This is the read for a task that is running but making no progress — the stack says whether it is blocked on a lock, waiting on a shuffle fetch, or spinning in user code. Only a live driver serves it; the history server does not. Heavier than the other reads: collecting the dump briefly pauses the executor's threads.","description":"Dump the stack traces of every thread in one live executor. This is the read for a task that is running but making no progress — the stack says whether it is blocked on a lock, waiting on a shuffle fetch, or spinning in user code. Only a live driver serves it; the history server does not. Heavier than the other reads: collecting the dump briefly pauses the executor's threads.","kind":"script","risk":"medium","side_effects":["One HTTP GET to the live driver, which asks the executor for a thread dump.","Read-only — no application, job, or executor state is changed.","Briefly pauses the executor's threads while stacks are collected.","Returns no application data — stack frames only."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications with source driver.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"executor_id","type":"string","required":true,"description":"Executor id, from spark.executors. \"driver\" dumps the driver's own threads.","validation":{"pattern":"^[A-Za-z0-9._-]{1,64}$","max_length":64}}],"examples":[{"title":"Why executor 1 is not progressing","args":{"app_id":"app-20260805120000-0001","executor_id":"1"}},{"title":"The driver's own threads","args":{"app_id":"app-20260805120000-0001","executor_id":"driver"}}],"search_terms":["thread dump","stuck task","deadlock","executor hung","no progress"]},{"id":"spark.executors","title":"List an application's executors (GET .../executors)","summary":"List an application's executors with cores, active and completed tasks, failed tasks, GC time, storage memory used against total, disk used, and their host and log URLs. Read it when an application is slow or losing work: a single executor with most of the failed tasks names the bad host.","description":"List an application's executors with cores, active and completed tasks, failed tasks, GC time, storage memory used against total, disk used, and their host and log URLs. Read it when an application is slow or losing work: a single executor with most of the failed tasks names the bad host.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"include_removed","type":"string","required":false,"default":"false","description":"Include executors that have already been removed (the allexecutors endpoint). That is what shows an executor lost mid-run, which the active list no longer mentions.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Active executors","args":{"app_id":"app-20260805120000-0001"}},{"title":"Including executors that were lost","args":{"app_id":"app-20260805120000-0001","include_removed":"true"}}],"search_terms":["spark executors","executor memory","lost executor","gc time","executor failures"]},{"id":"spark.job","title":"GET /api/v1/applications/{app_id}/jobs/{job_id}","summary":"Show one Spark job — status, timing, the stage ids it owns, and its task counts including failed and killed. Read it after spark.jobs narrows to the job you care about, then follow its stage ids into spark.stage.","description":"Show one Spark job — status, timing, the stage ids it owns, and its task counts including failed and killed. Read it after spark.jobs narrows to the job you care about, then follow its stage ids into spark.stage.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"job_id","type":"integer","required":true,"description":"Job id, from spark.jobs.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"One job","args":{"app_id":"app-20260805120000-0001","job_id":3}}],"search_terms":["spark job detail","job stages","job failure reason"]},{"id":"spark.job_kill","title":"Kill a running Spark job (POST /jobs/job/kill on the driver UI)","summary":"Kill one running job in the application on the live driver UI. Every task in the job is cancelled and the job is marked failed; whatever the job had already written stays written, so a partially completed output is the normal outcome. The action reads the job back afterwards and returns its state, so a request against an already-finished job is visible rather than assumed. Needs spark.ui.killEnabled, which is on by default.","description":"Kill one running job in the application on the live driver UI. Every task in the job is cancelled and the job is marked failed; whatever the job had already written stays written, so a partially completed output is the normal outcome. The action reads the job back afterwards and returns its state, so a request against an already-finished job is visible rather than assumed. Needs spark.ui.killEnabled, which is on by default.","kind":"script","risk":"high","side_effects":["Cancels every running task in the job; the job ends as failed.","Partial output the job already wrote is left in place.","The application keeps running; only this job is cancelled.","Whether the job was running is reported by reading it back, not assumed."],"args":[{"name":"job_id","type":"integer","required":true,"description":"Job id to kill, from spark.jobs with source driver.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Kill a job that will never finish","args":{"job_id":12}}],"search_terms":["kill spark job","cancel job","stop runaway job","runaway query"]},{"id":"spark.jobs","title":"List an application's jobs (GET /api/v1/applications/{app_id}/jobs)","summary":"List a Spark application's jobs with their status, submission time, duration, and task counts — completed, active, skipped, and failed. Filter by `status: failed` to find the job that broke, or `status: running` to see what a stuck application is still working on.","description":"List a Spark application's jobs with their status, submission time, duration, and task counts — completed, active, skipped, and failed. Filter by `status: failed` to find the job that broke, or `status: running` to see what a stuck application is still working on.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to jobs in this state. Empty returns every job.","validation":{"enum":["","running","succeeded","failed","unknown"]}}],"examples":[{"title":"Every job in an application","args":{"app_id":"app-20260805120000-0001"}},{"title":"The failed jobs of a live application","args":{"app_id":"app-20260805120000-0001","source":"driver","status":"failed"}}],"search_terms":["spark jobs","failed job","running job","what is the app doing"]},{"id":"spark.master_app_kill","title":"Kill an application from the standalone master (POST /app/kill)","summary":"Kill one whole application on a Spark standalone master. Its driver and every executor are terminated and its cores and memory return to the cluster — which is the point when one application is starving everything else — but the application's work stops wherever it was, so partial output stays partial. The action reads the master's state back and reports whether the application is still active.","description":"Kill one whole application on a Spark standalone master. Its driver and every executor are terminated and its cores and memory return to the cluster — which is the point when one application is starving everything else — but the application's work stops wherever it was, so partial output stays partial. The action reads the master's state back and reports whether the application is still active.","kind":"script","risk":"high","side_effects":["Terminates the application's driver and every one of its executors.","In-flight work is lost; whatever was already written stays written.","Frees the application's cores and memory for other applications.","Whether the application ended is reported by reading the master back, not assumed."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id to kill, e.g. app-20260805120000-0001, from spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill the application that is holding every core","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["kill spark application","free up cores","stop the app","application starving the cluster"]},{"id":"spark.master_driver_kill","title":"Kill a cluster-mode driver from the standalone master (POST /driver/kill)","summary":"Kill one cluster-mode driver on a Spark standalone master. The driver process and the application it runs are terminated. Use it for a submitted job whose client is long gone — a driver stuck in a retry loop, or one submitted by mistake. The action reads the master's state back and reports whether the driver is still active.","description":"Kill one cluster-mode driver on a Spark standalone master. The driver process and the application it runs are terminated. Use it for a submitted job whose client is long gone — a driver stuck in a retry loop, or one submitted by mistake. The action reads the master's state back and reports whether the driver is still active.","kind":"script","risk":"high","side_effects":["Terminates the driver process and the application it is running.","In-flight work is lost; whatever was already written stays written.","A driver submitted with supervise is not restarted after an explicit kill.","Whether the driver ended is reported by reading the master back, not assumed."],"args":[{"name":"driver_id","type":"string","required":true,"description":"Driver id to kill, e.g. driver-20260805120000-0003, from spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a driver stuck restarting","args":{"driver_id":"driver-20260805120000-0003"}}],"search_terms":["kill spark driver","stop cluster mode job","driver retry loop"]},{"id":"spark.master_state","title":"Show standalone cluster state (GET /json/ on the master)","summary":"Show a Spark standalone master's cluster state — every worker with its state, cores and memory used against total, the running and completed applications with the resources each holds, and any submitted drivers. This is the capacity read: an application stuck in WAITING with no free cores means the cluster is full, not that the application is broken.","description":"Show a Spark standalone master's cluster state — every worker with its state, cores and memory used against total, the running and completed applications with the resources each holds, and any submitted drivers. This is the capacity read: an application stuck in WAITING with no free cores means the cluster is full, not that the application is broken.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the standalone master's web UI.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Cluster capacity and what is using it","args":{}}],"search_terms":["spark cluster state","workers alive","free cores","app waiting","standalone master"]},{"id":"spark.master_worker_decommission","title":"Decommission a standalone worker host (POST /workers/kill on the master)","summary":"Decommission every standalone worker on one host. Spark stops scheduling new tasks there and migrates shuffle and cached blocks off before the executors go away, which is the graceful way to take a node out for maintenance or a scale-down. Still a capacity change: the cluster loses that host's cores, and running tasks on it are rescheduled elsewhere. Needs spark.decommission.enabled and an allowed value of spark.master.ui.decommission.allow.mode; both are off or restrictive by default.","description":"Decommission every standalone worker on one host. Spark stops scheduling new tasks there and migrates shuffle and cached blocks off before the executors go away, which is the graceful way to take a node out for maintenance or a scale-down. Still a capacity change: the cluster loses that host's cores, and running tasks on it are rescheduled elsewhere. Needs spark.decommission.enabled and an allowed value of spark.master.ui.decommission.allow.mode; both are off or restrictive by default.","kind":"script","risk":"high","side_effects":["Stops scheduling new tasks on every worker on the host.","Migrates shuffle and cached blocks off the host, then removes its executors.","Tasks running on the host are rescheduled onto the remaining workers.","The cluster permanently loses that host's capacity until the worker is restarted."],"args":[{"name":"host","type":"string","required":true,"description":"Hostname or address of the worker host, as reported by spark.master_state.","validation":{"pattern":"^[A-Za-z0-9._:-]{1,253}$","max_length":253}}],"examples":[{"title":"Drain a node before maintenance","args":{"host":"spark-worker-3.internal"}}],"search_terms":["decommission worker","drain spark node","scale down cluster","node maintenance"]},{"id":"spark.sql_execution","title":"GET .../sql/{execution_id}","summary":"Show one Spark SQL execution with its node-level metrics — rows produced, bytes read, shuffle sizes, and time per operator — and optionally the physical plan. This is where a query's cost is attributed: the node with the row explosion or the full scan is named here.","description":"Show one Spark SQL execution with its node-level metrics — rows produced, bytes read, shuffle sizes, and time per operator — and optionally the physical plan. This is where a query's cost is attributed: the node with the row explosion or the full scan is named here.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","The plan and node descriptions include table, column, and literal values from the query."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"execution_id","type":"integer","required":true,"description":"SQL execution id, from spark.sql_executions.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"plan_description","type":"string","required":false,"default":"true","description":"Include the physical plan text.","validation":{"enum":["true","false"]}}],"examples":[{"title":"The plan and metrics for one query","args":{"app_id":"app-20260805120000-0001","execution_id":12}}],"search_terms":["query plan","physical plan","why is the query slow","full table scan","broadcast join"]},{"id":"spark.sql_executions","title":"List SQL executions (GET .../sql)","summary":"List an application's Spark SQL executions with their description, submission time, duration, and the jobs each one spawned. For a SQL or DataFrame workload this is the layer that maps a slow query to the jobs and stages underneath it.","description":"List an application's Spark SQL executions with their description, submission time, duration, and the jobs each one spawned. For a SQL or DataFrame workload this is the layer that maps a slow query to the jobs and stages underneath it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","Execution descriptions come from the submitted query and can include table and column names."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset within the application's executions.","validation":{"min":0,"max":1000000}},{"name":"length","type":"integer","required":false,"default":25,"description":"Executions returned in this page.","validation":{"min":1,"max":100}},{"name":"plan_description","type":"string","required":false,"default":"false","description":"Include the physical plan text for every execution. Off by default — a plan is large, and spark.sql_execution returns one on demand.","validation":{"enum":["true","false"]}}],"examples":[{"title":"SQL executions in an application","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["spark sql","slow query","dataframe execution","query duration"]},{"id":"spark.stage","title":"GET /api/v1/applications/{app_id}/stages/{stage_id}","summary":"Show every attempt of one stage with its status, task counts, timing, shuffle and spill metrics, and — with with_summaries — the task metric quantiles. A stage with more than one attempt has been retried, which usually means lost executors or a fetch failure.","description":"Show every attempt of one stage with its status, task counts, timing, shuffle and spill metrics, and — with with_summaries — the task metric quantiles. A stage with more than one attempt has been retried, which usually means lost executors or a fetch failure.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages or a job's stageIds.","validation":{"min":0,"max":1000000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"details","type":"string","required":false,"default":"false","description":"Include the per-task detail. Off by default — a wide stage has thousands of tasks.","validation":{"enum":["true","false"]}},{"name":"with_summaries","type":"string","required":false,"default":"false","description":"Include task and executor metric quantile summaries for the stage.","validation":{"enum":["true","false"]}}],"examples":[{"title":"One stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"One stage with its metric quantiles","args":{"app_id":"app-20260805120000-0001","stage_id":4,"with_summaries":"true"}}],"search_terms":["stage detail","stage retry","stage attempts","fetch failure"]},{"id":"spark.stage_kill","title":"Kill a running Spark stage (POST /stages/stage/kill on the driver UI)","summary":"Kill one running stage in the application on the live driver UI. Narrower than killing the job: the stage's tasks are cancelled, and whether the job survives depends on whether Spark can retry the stage. Use it to shed one runaway stage — a skewed shuffle, a stage stuck on a dead host — without losing the whole job. The action reads the stage back and returns its attempts. Needs spark.ui.killEnabled, which is on by default.","description":"Kill one running stage in the application on the live driver UI. Narrower than killing the job: the stage's tasks are cancelled, and whether the job survives depends on whether Spark can retry the stage. Use it to shed one runaway stage — a skewed shuffle, a stage stuck on a dead host — without losing the whole job. The action reads the stage back and returns its attempts. Needs spark.ui.killEnabled, which is on by default.","kind":"script","risk":"high","side_effects":["Cancels the running tasks in the stage.","The owning job fails unless Spark retries the stage successfully.","Partial shuffle output the stage wrote is discarded.","Whether the stage was running is reported by reading it back, not assumed."],"args":[{"name":"stage_id","type":"integer","required":true,"description":"Stage id to kill, from spark.stages with source driver.","validation":{"min":0,"max":1000000}}],"examples":[{"title":"Kill a stage stuck on one partition","args":{"stage_id":7}}],"search_terms":["kill spark stage","cancel stage","stuck stage","skewed shuffle"]},{"id":"spark.stage_task_summary","title":"Get task metric quantiles for a stage attempt (GET .../taskSummary)","summary":"Get the task metric quantiles for one stage attempt — duration, GC time, shuffle read and write, input bytes, and memory and disk spill at each quantile. This is the skew read: when the maximum task duration dwarfs the median, the stage is waiting on a few partitions, not on the cluster.","description":"Get the task metric quantiles for one stage attempt — duration, GC time, shuffle read and write, input bytes, and memory and disk spill at each quantile. This is the skew read: when the maximum task duration dwarfs the median, the stage is waiting on a few partitions, not on the cluster.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages.","validation":{"min":0,"max":1000000}},{"name":"attempt_id","type":"integer","required":false,"default":0,"description":"Stage attempt. 0 is the first attempt; spark.stage lists the rest.","validation":{"min":0,"max":1000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"quantiles","type":"string","required":false,"default":"0.05,0.25,0.5,0.75,0.95","description":"Comma-separated quantiles between 0 and 1.","validation":{"pattern":"^[0-9.]{1,4}(,[0-9.]{1,4}){0,9}$","max_length":50}}],"examples":[{"title":"Where the time went in a stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"The long tail only","args":{"app_id":"app-20260805120000-0001","quantiles":"0.5,0.9,0.99,1.0","stage_id":4}}],"search_terms":["data skew","straggler task","task quantiles","p99 task duration","gc time"]},{"id":"spark.stage_tasks","title":"List tasks in a stage attempt (GET .../taskList)","summary":"List individual tasks in one stage attempt with their executor, host, duration, status, and — for a failed task — the error message. Sort by `-runtime` to put the slowest first, or filter `status: failed` to read why the stage broke.","description":"List individual tasks in one stage attempt with their executor, host, duration, status, and — for a failed task — the error message. Sort by `-runtime` to put the slowest first, or filter `status: failed` to read why the stage broke.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data.","A failed task's error message is returned as Spark recorded it."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"stage_id","type":"integer","required":true,"description":"Stage id, from spark.stages.","validation":{"min":0,"max":1000000}},{"name":"attempt_id","type":"integer","required":false,"default":0,"description":"Stage attempt. 0 is the first attempt.","validation":{"min":0,"max":1000}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to tasks in this state. Empty returns every task in the page.","validation":{"enum":["","running","success","killed","failed","pending"]}},{"name":"sort_by","type":"string","required":false,"default":"-runtime","description":"Sort order for the page. Slowest first by default.","validation":{"enum":["-runtime","runtime","-executorRunTime","executorRunTime","-launchTime","launchTime"]}},{"name":"offset","type":"integer","required":false,"default":0,"description":"Page offset within the stage's tasks.","validation":{"min":0,"max":1000000}},{"name":"length","type":"integer","required":false,"default":25,"description":"Tasks returned in this page.","validation":{"min":1,"max":200}}],"examples":[{"title":"The slowest tasks in a stage","args":{"app_id":"app-20260805120000-0001","stage_id":4}},{"title":"Only the failures","args":{"app_id":"app-20260805120000-0001","stage_id":4,"status":"failed"}}],"search_terms":["failed tasks","slowest task","task error message","which executor"]},{"id":"spark.stages","title":"List an application's stages (GET /api/v1/applications/{app_id}/stages)","summary":"List a Spark application's stages with status, task counts, duration, shuffle read and write bytes, spill, and input and output sizes. This is where a slow job is diagnosed: the stage with the outsized shuffle read or spill is usually the one to look at.","description":"List a Spark application's stages with status, task counts, duration, shuffle read and write bytes, spill, and input and output sizes. This is where a slow job is diagnosed: the stage with the outsized shuffle read or spill is usually the one to look at.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}},{"name":"status","type":"string","required":false,"default":"","description":"Restrict to stages in this state. Empty returns every stage.","validation":{"enum":["","active","complete","pending","failed","skipped"]}},{"name":"details","type":"string","required":false,"default":"false","description":"Include the per-task detail for every stage. Off by default — on a large application it turns a summary into megabytes.","validation":{"enum":["true","false"]}}],"examples":[{"title":"Every stage in an application","args":{"app_id":"app-20260805120000-0001"}},{"title":"The stages still running on a live driver","args":{"app_id":"app-20260805120000-0001","source":"driver","status":"active"}}],"search_terms":["spark stages","shuffle read","spill to disk","slow stage","failed stage"]},{"id":"spark.storage_rdds","title":"List cached RDDs (GET .../storage/rdd)","summary":"List the RDDs and DataFrames an application has cached, with their storage level, partition count, and how many bytes sit in memory versus spilled to disk. Read it when executors are short on memory: a large cache that is mostly on disk is paying the cost of caching without the benefit.","description":"List the RDDs and DataFrames an application has cached, with their storage level, partition count, and how many bytes sit in memory versus spilled to disk. Read it when executors are short on memory: a large cache that is mostly on disk is paying the cost of caching without the benefit.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"app_id","type":"string","required":true,"description":"Application id, from spark.applications.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}},{"name":"source","type":"string","required":false,"default":"driver","description":"Which UI to ask. Storage is live state, so a driver ($SPARK_UI_URL) is the default; the history server reports what was cached when the event log was written.","validation":{"enum":["history","driver"]}}],"examples":[{"title":"What this application has cached","args":{"app_id":"app-20260805120000-0001"}}],"search_terms":["cached rdd","persist","memory used","spilled to disk","storage level"]},{"id":"spark.submission_kill","title":"Kill a REST submission (POST /v1/submissions/kill/{id})","summary":"Kill one cluster-mode submission through the standalone REST submission server. The driver and its application are terminated, and the server answers with whether it found and killed the submission. This is the path for a job submitted with `spark-submit --deploy-mode cluster` when you have the submission id but not the master UI. Needs spark.master.rest.enabled, which is off by default.","description":"Kill one cluster-mode submission through the standalone REST submission server. The driver and its application are terminated, and the server answers with whether it found and killed the submission. This is the path for a job submitted with `spark-submit --deploy-mode cluster` when you have the submission id but not the master UI. Needs spark.master.rest.enabled, which is off by default.","kind":"script","risk":"high","side_effects":["Terminates the submitted driver and the application it is running.","In-flight work is lost; whatever was already written stays written.","The server reports whether the submission was found and killed."],"args":[{"name":"submission_id","type":"string","required":true,"description":"Submission id to kill, e.g. driver-20260805120000-0003.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Kill a submitted job by id","args":{"submission_id":"driver-20260805120000-0003"}}],"search_terms":["kill submission","cancel spark-submit","stop cluster mode driver"]},{"id":"spark.submission_status","title":"Get a REST submission's status (GET /v1/submissions/status/{id})","summary":"Get the state of one cluster-mode submission from the standalone REST submission server — whether the driver is queued, running, finished, or failed, and the worker it landed on. Use it to follow a `spark-submit --deploy-mode cluster` job whose client already exited. Needs spark.master.rest.enabled, which is off by default.","description":"Get the state of one cluster-mode submission from the standalone REST submission server — whether the driver is queued, running, finished, or failed, and the worker it landed on. Use it to follow a `spark-submit --deploy-mode cluster` job whose client already exited. Needs spark.master.rest.enabled, which is off by default.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the standalone REST submission server.","Read-only — never writes or mutates data."],"args":[{"name":"submission_id","type":"string","required":true,"description":"Submission id, e.g. driver-20260805120000-0003, as returned when the job was submitted.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$","max_length":128}}],"examples":[{"title":"Where a cluster-mode driver got to","args":{"submission_id":"driver-20260805120000-0003"}}],"search_terms":["submission status","driver state","cluster deploy mode","spark-submit status"]},{"id":"spark.version","title":"GET /api/v1/version","summary":"Show the Spark version a UI is running. Use it to confirm a driver or history server is reachable and which release it is on before reading a version-specific field.","description":"Show the Spark version a UI is running. Use it to confirm a driver or history server is reachable and which release it is on before reading a version-specific field.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Spark monitoring API.","Read-only — never writes or mutates data."],"args":[{"name":"source","type":"string","required":false,"default":"history","description":"Which UI to ask — the history server ($SPARK_HISTORY_URL) or a live driver ($SPARK_UI_URL).","validation":{"enum":["history","driver"]}}],"examples":[{"title":"History server version","args":{}},{"title":"Live driver version","args":{"source":"driver"}}],"search_terms":["spark version","which release"]}]}]},{"id":"ssl-local","name":"Local SSL/TLS cert inspection","version":"0.1.14","description":"Inspect TLS certificates and keys on the local filesystem — find PEMs under a path, dump x509 details, check chain, verify private-key match, inspect PKCS#12. Read-only. Pair with `network-tls` for the remote-side view.","vendor":"emisar","homepage":"https://emisar.dev/packs/ssl-local","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/ssl-local","content_hash":"sha256:ba39e677c2ec96da6d867b646db6869c882dd5865d06b45139b29be3cdf8a946","tarball_url":"https://registry.emisar.dev/v1/packs/ssl-local/0.1.14/ba39e677c2ec96da6d867b646db6869c882dd5865d06b45139b29be3cdf8a946/pack.tar.gz","requires":{"os":["linux"],"binaries":["openssl"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Inspects certificate and key files on the local runner host's filesystem at the paths you pass as action arguments — no credentials needed.","host_access":[{"actions":["ssl.find_certs","ssl.cert_text","ssl.cert_expiry","ssl.cert_fingerprint","ssl.key_modulus","ssl.verify_chain","ssl.pkcs12_info"],"requirement":"Read root-owned or otherwise restricted certificate, key, and PKCS#12 files.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-ssl-local-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. These reads can reach private keys and PKCS#12 bundles even though pack output never intentionally prints key bytes."}]}],"verify":"ssl.cert_expiry"},"actions":[{"id":"ssl.cert_expiry","title":"openssl x509 -enddate -subject","summary":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","description":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Expiry of one cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-subject","-issuer","-startdate","-enddate"]}},{"id":"ssl.cert_fingerprint","title":"openssl x509 -fingerprint -sha256","summary":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","description":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"SHA-256 of cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-fingerprint","-sha256"]}},{"id":"ssl.cert_text","title":"openssl x509 -text -noout","summary":"Dump a human-readable x509 certificate.","description":"Dump a human-readable x509 certificate.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Inspect cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-text","-noout"]}},{"id":"ssl.find_certs","title":"find *.pem *.crt *.cer under <path>","summary":"List certificate-like files under one path.","description":"List certificate-like files under one path.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"string","required":false,"default":"/etc/ssl","description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Cert files under /etc/ssl","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\nfind \"$1\" -xdev -type f \\( -name '*.pem' -o -name '*.crt' -o -name '*.cer' \\) -print 2>/dev/null | head -500\n","emisar","{{ args.path }}"]}},{"id":"ssl.key_modulus","title":"openssl rsa -modulus | sha256","summary":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","description":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — only the modulus hash is emitted; the key material is not returned."],"args":[{"name":"path","type":"string","required":true,"description":"Key file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Modulus hash of key","args":{"path":"/etc/ssl/private/server.key"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","modulus=$(openssl rsa -in \"$1\" -modulus -noout) || exit 1\n[ -n \"$modulus\" ] || { echo \"no modulus read from $1\" >&2; exit 1; }\nprintf '%s' \"$modulus\" | sha256sum\n","emisar","{{ args.path }}"]}},{"id":"ssl.pkcs12_info","title":"openssl pkcs12 -nokeys -info","summary":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","description":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — private keys NOT printed."],"args":[{"name":"path","type":"string","required":true,"description":".p12 / .pfx file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"allowed_prefixes":["/etc/ssl/","/etc/pki/","/usr/local/share/ca-certificates/"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Bag contents","args":{"path":"/etc/ssl/private/server.p12"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl pkcs12 -in \"$1\" -nokeys -info -passin env:PK12_PASSWORD 2>&1","emisar","{{ args.path }}"]}},{"id":"ssl.verify_chain","title":"openssl verify -CAfile <bundle> <cert>","summary":"Verify that a cert chains to a trusted root via a given CA bundle.","description":"Verify that a cert chains to a trusted root via a given CA bundle.","kind":"exec","risk":"low","side_effects":["Two file reads.","Read-only."],"args":[{"name":"cert","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}},{"name":"ca_bundle","type":"string","required":false,"default":"/etc/ssl/certs/ca-certificates.crt","description":"Trusted CA bundle.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Verify cert against system bundle","args":{"cert":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["verify","-CAfile","{{ args.ca_bundle }}","{{ args.cert }}"]}}],"previous_versions":[{"version":"0.1.12","content_hash":"sha256:18b6d3a99996193ba466dfa939f2cb577275cea8cc591eed231771c1313780ad","tarball_url":"https://registry.emisar.dev/v1/packs/ssl-local/0.1.12/18b6d3a99996193ba466dfa939f2cb577275cea8cc591eed231771c1313780ad/pack.tar.gz","actions":[{"id":"ssl.cert_expiry","title":"openssl x509 -enddate -subject","summary":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","description":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Expiry of one cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-subject","-issuer","-startdate","-enddate"]}},{"id":"ssl.cert_fingerprint","title":"openssl x509 -fingerprint -sha256","summary":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","description":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"SHA-256 of cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-fingerprint","-sha256"]}},{"id":"ssl.cert_text","title":"openssl x509 -text -noout","summary":"Dump a human-readable x509 certificate.","description":"Dump a human-readable x509 certificate.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Inspect cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-text","-noout"]}},{"id":"ssl.find_certs","title":"find *.pem *.crt *.cer under <path>","summary":"List certificate-like files under one path.","description":"List certificate-like files under one path.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"string","required":false,"default":"/etc/ssl","description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Cert files under /etc/ssl","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\nfind \"$1\" -xdev -type f \\( -name '*.pem' -o -name '*.crt' -o -name '*.cer' \\) -print 2>/dev/null | head -500\n","emisar","{{ args.path }}"]}},{"id":"ssl.key_modulus","title":"openssl rsa -modulus | sha256","summary":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","description":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — only the modulus hash is emitted; the key material is not returned."],"args":[{"name":"path","type":"string","required":true,"description":"Key file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Modulus hash of key","args":{"path":"/etc/ssl/private/server.key"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","modulus=$(openssl rsa -in \"$1\" -modulus -noout) || exit 1\n[ -n \"$modulus\" ] || { echo \"no modulus read from $1\" >&2; exit 1; }\nprintf '%s' \"$modulus\" | sha256sum\n","emisar","{{ args.path }}"]}},{"id":"ssl.pkcs12_info","title":"openssl pkcs12 -nokeys -info","summary":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","description":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — private keys NOT printed."],"args":[{"name":"path","type":"string","required":true,"description":".p12 / .pfx file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"allowed_prefixes":["/etc/ssl/","/etc/pki/","/usr/local/share/ca-certificates/"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Bag contents","args":{"path":"/etc/ssl/private/server.p12"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl pkcs12 -in \"$1\" -nokeys -info -passin env:PK12_PASSWORD 2>&1","emisar","{{ args.path }}"]}},{"id":"ssl.verify_chain","title":"openssl verify -CAfile <bundle> <cert>","summary":"Verify that a cert chains to a trusted root via a given CA bundle.","description":"Verify that a cert chains to a trusted root via a given CA bundle.","kind":"exec","risk":"low","side_effects":["Two file reads.","Read-only."],"args":[{"name":"cert","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}},{"name":"ca_bundle","type":"string","required":false,"default":"/etc/ssl/certs/ca-certificates.crt","description":"Trusted CA bundle.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Verify cert against system bundle","args":{"cert":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["verify","-CAfile","{{ args.ca_bundle }}","{{ args.cert }}"]}}]},{"version":"0.1.11","content_hash":"sha256:3faeb5d0a194cb84c358ba8e89fd00d5dcb2b7aaade5568f8049678741a2dd8f","tarball_url":"https://registry.emisar.dev/v1/packs/ssl-local/0.1.11/3faeb5d0a194cb84c358ba8e89fd00d5dcb2b7aaade5568f8049678741a2dd8f/pack.tar.gz","actions":[{"id":"ssl.cert_expiry","title":"openssl x509 -enddate -subject","summary":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","description":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Expiry of one cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-subject","-issuer","-startdate","-enddate"]}},{"id":"ssl.cert_fingerprint","title":"openssl x509 -fingerprint -sha256","summary":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","description":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"SHA-256 of cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-fingerprint","-sha256"]}},{"id":"ssl.cert_text","title":"openssl x509 -text -noout","summary":"Dump a human-readable x509 certificate.","description":"Dump a human-readable x509 certificate.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Inspect cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-text","-noout"]}},{"id":"ssl.find_certs","title":"find *.pem *.crt *.cer under <path>","summary":"List certificate-like files under one path.","description":"List certificate-like files under one path.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"string","required":false,"default":"/etc/ssl","description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Cert files under /etc/ssl","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\nfind \"$1\" -xdev -type f \\( -name '*.pem' -o -name '*.crt' -o -name '*.cer' \\) -print 2>/dev/null | head -500\n","emisar","{{ args.path }}"]}},{"id":"ssl.key_modulus","title":"openssl rsa -modulus | sha256","summary":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","description":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — only the modulus hash is emitted; the key material is not returned."],"args":[{"name":"path","type":"string","required":true,"description":"Key file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Modulus hash of key","args":{"path":"/etc/ssl/private/server.key"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","modulus=$(openssl rsa -in \"$1\" -modulus -noout) || exit 1\n[ -n \"$modulus\" ] || { echo \"no modulus read from $1\" >&2; exit 1; }\nprintf '%s' \"$modulus\" | sha256sum\n","emisar","{{ args.path }}"]}},{"id":"ssl.pkcs12_info","title":"openssl pkcs12 -nokeys -info","summary":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","description":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — private keys NOT printed."],"args":[{"name":"path","type":"string","required":true,"description":".p12 / .pfx file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"allowed_prefixes":["/etc/ssl/","/etc/pki/","/usr/local/share/ca-certificates/"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Bag contents","args":{"path":"/etc/ssl/private/server.p12"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl pkcs12 -in \"$1\" -nokeys -info -passin env:PK12_PASSWORD 2>&1","emisar","{{ args.path }}"]}},{"id":"ssl.verify_chain","title":"openssl verify -CAfile <bundle> <cert>","summary":"Verify that a cert chains to a trusted root via a given CA bundle.","description":"Verify that a cert chains to a trusted root via a given CA bundle.","kind":"exec","risk":"low","side_effects":["Two file reads.","Read-only."],"args":[{"name":"cert","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}},{"name":"ca_bundle","type":"string","required":false,"default":"/etc/ssl/certs/ca-certificates.crt","description":"Trusted CA bundle.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Verify cert against system bundle","args":{"cert":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["verify","-CAfile","{{ args.ca_bundle }}","{{ args.cert }}"]}}]},{"version":"0.1.10","content_hash":"sha256:64d69d5ac13087622f4e04fca12d27f322a709aa05d6c4ecfcf7a9309163a0b7","tarball_url":"https://registry.emisar.dev/v1/packs/ssl-local/0.1.10/64d69d5ac13087622f4e04fca12d27f322a709aa05d6c4ecfcf7a9309163a0b7/pack.tar.gz","actions":[{"id":"ssl.cert_expiry","title":"openssl x509 -enddate -subject","summary":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","description":"Show cert expiry date + subject. Quick way to answer \"is this about to expire?\".","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Expiry of one cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-subject","-issuer","-startdate","-enddate"]}},{"id":"ssl.cert_fingerprint","title":"openssl x509 -fingerprint -sha256","summary":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","description":"Show the SHA-256 fingerprint of the cert. Use for pinning checks.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"SHA-256 of cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-noout","-fingerprint","-sha256"]}},{"id":"ssl.cert_text","title":"openssl x509 -text -noout","summary":"Dump a human-readable x509 certificate.","description":"Dump a human-readable x509 certificate.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[{"name":"path","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Inspect cert","args":{"path":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["x509","-in","{{ args.path }}","-text","-noout"]}},{"id":"ssl.find_certs","title":"find *.pem *.crt *.cer under <path>","summary":"Lists certificate-like files under one path.","description":"Lists certificate-like files under one path.","kind":"exec","risk":"low","side_effects":["One file-system traversal.","Read-only."],"args":[{"name":"path","type":"string","required":false,"default":"/etc/ssl","description":"Root path.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{0,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Cert files under /etc/ssl","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","[ -d \"$1\" ] || { echo \"not a readable directory: $1\" >&2; exit 1; }\nfind \"$1\" -xdev -type f \\( -name '*.pem' -o -name '*.crt' -o -name '*.cer' \\) -print 2>/dev/null | head -500\n","emisar","{{ args.path }}"]}},{"id":"ssl.key_modulus","title":"openssl rsa -modulus | sha256","summary":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","description":"Show the hash of the RSA private key's modulus. Compare to the modulus hash of a cert (via `openssl x509 -modulus`) to confirm key + cert match. NEVER prints the key itself.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — only the modulus hash is emitted; the key material is not returned."],"args":[{"name":"path","type":"string","required":true,"description":"Key file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Modulus hash of key","args":{"path":"/etc/ssl/private/server.key"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","modulus=$(openssl rsa -in \"$1\" -modulus -noout) || exit 1\n[ -n \"$modulus\" ] || { echo \"no modulus read from $1\" >&2; exit 1; }\nprintf '%s' \"$modulus\" | sha256sum\n","emisar","{{ args.path }}"]}},{"id":"ssl.pkcs12_info","title":"openssl pkcs12 -nokeys -info","summary":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","description":"Inspect a PKCS#12 bundle's bag contents — cert subjects, key types — without exporting the private key. Requires the bundle's password via PK12_PASSWORD env var on the runner host (or empty for password-less bundles).","kind":"exec","risk":"low","side_effects":["One file read.","Read-only — private keys NOT printed."],"args":[{"name":"path","type":"string","required":true,"description":".p12 / .pfx file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"allowed_prefixes":["/etc/ssl/","/etc/pki/","/usr/local/share/ca-certificates/"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Bag contents","args":{"path":"/etc/ssl/private/server.p12"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","openssl pkcs12 -in \"$1\" -nokeys -info -passin env:PK12_PASSWORD 2>&1","emisar","{{ args.path }}"]}},{"id":"ssl.verify_chain","title":"openssl verify -CAfile <bundle> <cert>","summary":"Verify that a cert chains to a trusted root via a given CA bundle.","description":"Verify that a cert chains to a trusted root via a given CA bundle.","kind":"exec","risk":"low","side_effects":["Two file reads.","Read-only."],"args":[{"name":"cert","type":"string","required":true,"description":"Cert file.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}},{"name":"ca_bundle","type":"string","required":false,"default":"/etc/ssl/certs/ca-certificates.crt","description":"Trusted CA bundle.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","denied_paths":["/etc/shadow","/etc/gshadow","/etc/shadow-","/etc/gshadow-"],"denied_prefixes":["/root/.ssh"]}}],"examples":[{"title":"Verify cert against system bundle","args":{"cert":"/etc/ssl/certs/server.crt"}}],"search_terms":[],"command":{"binary":"openssl","argv":["verify","-CAfile","{{ args.ca_bundle }}","{{ args.cert }}"]}}]}],"retired_below":"0.1.7"},{"id":"symbolicator","name":"Symbolicator native symbolication","version":"0.2.4","description":"Debug native crashes with Symbolicator and keep the host it runs on healthy. Symbolicate a stack trace, a minidump, or an Apple crash report against the debug files the operator's configured sources hold, follow a request that runs long, and manage what that costs: liveness, build version, the cache footprint filling the disk, and the cleanup — previewed before it runs. Nothing here can publish or alter a symbol; Symbolicator has no ingest path. For the Sentry API itself, see the sentry pack.","vendor":"emisar","homepage":"https://emisar.dev/packs/symbolicator","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/symbolicator","content_hash":"sha256:130564baa6c283f352ada87430b93198167678ccd9362a98da7f6be856eec11f","tarball_url":"https://registry.emisar.dev/v1/packs/symbolicator/0.2.4/130564baa6c283f352ada87430b93198167678ccd9362a98da7f6be856eec11f/pack.tar.gz","requires":{"os":["linux"],"binaries":["symbolicator","curl","jq"]},"detect":{"binaries":["symbolicator"],"processes":["symbolicator"],"ports":[3021]},"setup":{"summary":"The HTTP reads call Symbolicator's own unauthenticated API on the host (127.0.0.1:3021 by default); the CLI actions run the symbolicator binary against the configuration the service uses. Neither takes credentials — Symbolicator has no auth of its own, so restrict reachability at the host.","env":[{"name":"SYMBOLICATOR_URL","description":"Base URL of the local Symbolicator HTTP API.","default":"http://127.0.0.1:3021"},{"name":"SYMBOLICATOR_CONFIG","description":"Configuration file the CLI actions read.","default":"/etc/symbolicator/config.yml"},{"name":"SYMBOLICATOR_CACHE_DIR","description":"Cache root, when it should not be read from the configuration's cache_dir. Falls back to /data, the image and self-hosted default."}],"notes":["Any of these you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so a variable present on the host but not allowlisted is silently dropped and the action falls back to its default.","Symbolicator's API is unauthenticated by design; it expects to be reachable only from Sentry's own network. These actions do not add authentication, they inherit whatever the host allows."],"host_access":[{"actions":["symbolicator.symbolicate_minidump","symbolicator.symbolicate_apple_crash","symbolicator.cache_usage","symbolicator.cleanup_preview","symbolicator.cleanup","symbolicator.config_show"],"requirement":"Read protected crash inputs, configuration, and cache, and delete expired cache entries.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-symbolicator-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. The configuration may contain source credentials, and cleanup can delete every cache entry Symbolicator deems expired."}]}],"verify":"symbolicator.health"},"actions":[{"id":"symbolicator.cache_usage","title":"Symbolicator cache footprint","summary":"Show how much disk each Symbolicator cache holds, largest first, with the filesystem underneath it. The caches — objects, symcaches, cficaches and the rest — are what fills a symbolication host, and they grow at very different rates, so this is the read to take before deciding whether a cleanup is the answer.","description":"Show how much disk each Symbolicator cache holds, largest first, with the filesystem underneath it. The caches — objects, symcaches, cficaches and the rest — are what fills a symbolication host, and they grow at very different rates, so this is the read to take before deciding whether a cleanup is the answer.","kind":"script","risk":"low","side_effects":["Walks the cache directories to size them, which is disk-read heavy on a large cache.","Reads filesystem metadata only.","Read-only."],"args":[],"examples":[{"title":"Which cache is eating the disk?","args":{}}],"search_terms":["disk full","symbol cache size"]},{"id":"symbolicator.cleanup","title":"symbolicator cleanup","summary":"Delete the cache entries that have gone unused past their configured retention, reclaiming disk. This is Symbolicator's own routine maintenance, bounded by the retention windows in its configuration — not a wipe. Preview it with symbolicator.cleanup_preview first.","description":"Delete the cache entries that have gone unused past their configured retention, reclaiming disk. This is Symbolicator's own routine maintenance, bounded by the retention windows in its configuration — not a wipe. Preview it with symbolicator.cleanup_preview first.","kind":"exec","risk":"medium","side_effects":["Removes cached debug files and derived caches whose retention has expired; a later symbolication that needs one re-downloads it from the configured symbol sources.","Symbolication is slower until the working set is cached again, and the re-download costs bandwidth against those sources.","Runs while the service serves; it does not restart or interrupt Symbolicator.","Reclaims nothing when the caches are within retention, which is what the preview reports."],"args":[],"examples":[{"title":"Reclaim expired cache entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ -f \"$config\" ]; then exec symbolicator cleanup -c \"$config\"; else exec symbolicator cleanup; fi"]}},{"id":"symbolicator.cleanup_preview","title":"symbolicator cleanup --dry-run","summary":"Show what a cache cleanup would remove and what it would keep, per cache, without deleting anything. Symbolicator prints retained and removed byte counts for each cache, so this is the read that decides whether symbolicator.cleanup is worth running.","description":"Show what a cache cleanup would remove and what it would keep, per cache, without deleting anything. Symbolicator prints retained and removed byte counts for each cache, so this is the read that decides whether symbolicator.cleanup is worth running.","kind":"exec","risk":"low","side_effects":["Walks the caches to evaluate their retention, which is disk-read heavy on a large cache.","Deletes nothing.","Read-only."],"args":[],"examples":[{"title":"What would a cleanup reclaim?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ -f \"$config\" ]; then exec symbolicator cleanup --dry-run -c \"$config\"; else exec symbolicator cleanup --dry-run; fi"]}},{"id":"symbolicator.config_show","title":"Show symbolicator config.yml","summary":"Dump the Symbolicator configuration this host runs — cache root, retention windows, bind address, and the symbol sources. Reading it is how you explain why a cleanup reclaimed nothing or why a symbol never resolves. High risk on purpose: the sources block is operator-authored and routinely holds S3, GCS, or HTTP credentials, so the whole file is treated as secret-bearing rather than trusted to a pattern.","description":"Dump the Symbolicator configuration this host runs — cache root, retention windows, bind address, and the symbol sources. Reading it is how you explain why a cleanup reclaimed nothing or why a symbol never resolves. High risk on purpose: the sources block is operator-authored and routinely holds S3, GCS, or HTTP credentials, so the whole file is treated as secret-bearing rather than trusted to a pattern.","kind":"exec","risk":"high","side_effects":["Reads the configuration file and returns its contents.","Credential-shaped keys are masked on the way out, but the key space is the operator's, so a credential under a name we do not model would reach the caller.","Read-only."],"args":[],"examples":[{"title":"What configuration is this host running?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ ! -f \"$config\" ]; then printf 'no configuration at %s — the service is running on built-in defaults\\n' \"$config\" >&2; exit 1; fi; exec cat \"$config\""]}},{"id":"symbolicator.health","title":"GET /healthcheck","summary":"Check whether Symbolicator is serving on this host. Answers \"ok\" while the HTTP server is up; a connection error means the service is down or bound somewhere other than SYMBOLICATOR_URL.","description":"Check whether Symbolicator is serving on this host. Answers \"ok\" while the HTTP server is up; a connection error means the service is down or bound somewhere other than SYMBOLICATOR_URL.","kind":"exec","risk":"low","side_effects":["One HTTP GET to the local service.","Read-only."],"args":[],"examples":[{"title":"Is Symbolicator serving?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec curl -q -fsS --globoff --proto \"=http,https\" --max-time 10 \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/healthcheck\""]}},{"id":"symbolicator.request_status","title":"GET /requests/<id>","summary":"Show the status of one symbolication request by its id — whether it is still pending or has completed, and its result when it has. Use it when Sentry reports a symbolication that never came back. An unknown or expired id answers 404.","description":"Show the status of one symbolication request by its id — whether it is still pending or has completed, and its result when it has. Use it when Sentry reports a symbolication that never came back. An unknown or expired id answers 404.","kind":"exec","risk":"low","side_effects":["One HTTP GET to the local service.","Waits up to the requested timeout for a pending request to finish.","Read-only."],"args":[{"name":"request_id","type":"string","required":true,"description":"Request id Symbolicator returned when the symbolication was accepted.","validation":{"pattern":"^[A-Za-z0-9_-]{1,128}$","max_length":128}},{"name":"timeout_seconds","type":"integer","required":false,"default":0,"description":"Seconds to wait for a pending request before answering; 0 returns its current state.","validation":{"min":0,"max":60}}],"examples":[{"title":"Where did this symbolication get to?","args":{"request_id":"e5f2b7a1c0d34e1fa9b8c7d6e5f4a3b2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec curl -q -fsS --globoff --proto \"=http,https\" --max-time 90 \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/requests/$1?timeout=$2\"","emisar","{{ args.request_id }}","{{ args.timeout_seconds }}"]}},{"id":"symbolicator.symbolicate","title":"POST /symbolicate","summary":"Symbolicate a native stack trace — turn instruction addresses into function names, files, and line numbers using the debug files this Symbolicator already has access to. Send the crash's modules and frames; the symbols come from the sources the operator configured, never from the request.","description":"Symbolicate a native stack trace — turn instruction addresses into function names, files, and line numbers using the debug files this Symbolicator already has access to. Send the crash's modules and frames; the symbols come from the sources the operator configured, never from the request.","kind":"exec","risk":"low","side_effects":["Resolves against the configured symbol sources; a debug file not cached yet is downloaded from them, which costs bandwidth and fills the caches.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol.","Returns symbolicated frames, and source context when a source bundle covers them."],"args":[{"name":"payload","type":"string","required":true,"description":"JSON object with `modules` (each with type, debug_id, code_file, image_addr, image_size) and `stacktraces` (each with `frames` carrying instruction_addr). An `options` object is optional. Any other key, including `sources`, is dropped before the request is sent.","validation":{"max_length":262144}}],"examples":[{"title":"Resolve one frame in a Windows module","args":{"payload":"{\"modules\":[{\"type\":\"pe\",\"debug_id\":\"3249d99d-0c40-4931-8610-f4e4fb0b6936-1\",\"code_file\":\"C:\\\\Windows\\\\System32\\\\kernel32.dll\",\"image_addr\":\"0x749d0000\",\"image_size\":851968}],\"stacktraces\":[{\"registers\":{},\"frames\":[{\"instruction_addr\":\"0x749e8630\"}]}]}"}}],"search_terms":["resolve stack trace","crash addresses to function names"],"command":{"binary":"/bin/sh","argv":["-c","body=$(printf '%s' \"$1\" | jq -c '{options: (.options // {dif_candidates: true}), modules: (.modules // []), stacktraces: (.stacktraces // [])}') || { printf 'payload must be a JSON object with modules and stacktraces\\n' >&2; exit 2; }; printf '%s' \"$body\" | curl -q -fsS --globoff --proto \"=http,https\" --max-time 180 -H 'content-type: application/json' --data-binary @- \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/symbolicate\"","emisar","{{ args.payload }}"]}},{"id":"symbolicator.symbolicate_apple_crash","title":"POST /applecrashreport","summary":"Symbolicate an Apple crash report already on this host — the iOS or macOS .crash text a device produced — against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","description":"Symbolicate an Apple crash report already on this host — the iOS or macOS .crash text a device produced — against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","kind":"exec","risk":"low","side_effects":["Reads the named report and sends its contents to the local symbolication service.","Resolves against the configured symbol sources; a dSYM not cached yet is downloaded from them.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol."],"args":[{"name":"path","type":"string","required":true,"description":"Apple crash report file on this host.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/var/lib/systemd/coredump","/var/crash","/var/tmp","/tmp","/data"],"max_length":512}}],"examples":[{"title":"Symbolicate a report pulled off a device","args":{"path":"/var/tmp/MyApp-2026-08-12-100731.crash"}}],"search_terms":["ios crash","macos crash report","dsym"],"command":{"binary":"/bin/sh","argv":["-c","exec curl -q -fsS --globoff --proto \"=http,https\" --max-time 300 -F \"apple_crash_report=@$1\" \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/applecrashreport\"","emisar","{{ args.path }}"]}},{"id":"symbolicator.symbolicate_minidump","title":"POST /minidump","summary":"Symbolicate a minidump already on this host — the crashing thread, its stack, and the loaded modules, resolved against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","description":"Symbolicate a minidump already on this host — the crashing thread, its stack, and the loaded modules, resolved against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","kind":"exec","risk":"low","side_effects":["Reads the named dump and sends its bytes to the local symbolication service.","Resolves against the configured symbol sources; a debug file not cached yet is downloaded from them.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol."],"args":[{"name":"path","type":"string","required":true,"description":"Minidump file on this host.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/var/lib/systemd/coredump","/var/crash","/var/tmp","/tmp","/data"],"max_length":512}}],"examples":[{"title":"Symbolicate a dump systemd-coredump kept","args":{"path":"/var/lib/systemd/coredump/core.myapp.1000.dmp"}}],"search_terms":["crash dump","core dump symbolication"],"command":{"binary":"/bin/sh","argv":["-c","exec curl -q -fsS --globoff --proto \"=http,https\" --max-time 300 -F \"upload_file_minidump=@$1\" \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/minidump\"","emisar","{{ args.path }}"]}},{"id":"symbolicator.version","title":"symbolicator --version","summary":"Show the Symbolicator build installed on this host — release version and git commit. Reports the binary on disk, which is what a restart would start.","description":"Show the Symbolicator build installed on this host — release version and git commit. Reports the binary on disk, which is what a restart would start.","kind":"exec","risk":"low","side_effects":["Reads the binary's build information.","Read-only."],"args":[],"examples":[{"title":"Installed build","args":{}}],"search_terms":[],"command":{"binary":"symbolicator","argv":["--version"]}}],"previous_versions":[{"version":"0.2.2","content_hash":"sha256:03ef17b664afbf875cafac88e2aac11a85b92f36f73ec980a62700da6503d0cd","tarball_url":"https://registry.emisar.dev/v1/packs/symbolicator/0.2.2/03ef17b664afbf875cafac88e2aac11a85b92f36f73ec980a62700da6503d0cd/pack.tar.gz","actions":[{"id":"symbolicator.cache_usage","title":"Symbolicator cache footprint","summary":"Show how much disk each Symbolicator cache holds, largest first, with the filesystem underneath it. The caches — objects, symcaches, cficaches and the rest — are what fills a symbolication host, and they grow at very different rates, so this is the read to take before deciding whether a cleanup is the answer.","description":"Show how much disk each Symbolicator cache holds, largest first, with the filesystem underneath it. The caches — objects, symcaches, cficaches and the rest — are what fills a symbolication host, and they grow at very different rates, so this is the read to take before deciding whether a cleanup is the answer.","kind":"script","risk":"low","side_effects":["Walks the cache directories to size them, which is disk-read heavy on a large cache.","Reads filesystem metadata only.","Read-only."],"args":[],"examples":[{"title":"Which cache is eating the disk?","args":{}}],"search_terms":["disk full","symbol cache size"]},{"id":"symbolicator.cleanup","title":"symbolicator cleanup","summary":"Delete the cache entries that have gone unused past their configured retention, reclaiming disk. This is Symbolicator's own routine maintenance, bounded by the retention windows in its configuration — not a wipe. Preview it with symbolicator.cleanup_preview first.","description":"Delete the cache entries that have gone unused past their configured retention, reclaiming disk. This is Symbolicator's own routine maintenance, bounded by the retention windows in its configuration — not a wipe. Preview it with symbolicator.cleanup_preview first.","kind":"exec","risk":"medium","side_effects":["Removes cached debug files and derived caches whose retention has expired; a later symbolication that needs one re-downloads it from the configured symbol sources.","Symbolication is slower until the working set is cached again, and the re-download costs bandwidth against those sources.","Runs while the service serves; it does not restart or interrupt Symbolicator.","Reclaims nothing when the caches are within retention, which is what the preview reports."],"args":[],"examples":[{"title":"Reclaim expired cache entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ -f \"$config\" ]; then exec symbolicator cleanup -c \"$config\"; else exec symbolicator cleanup; fi"]}},{"id":"symbolicator.cleanup_preview","title":"symbolicator cleanup --dry-run","summary":"Show what a cache cleanup would remove and what it would keep, per cache, without deleting anything. Symbolicator prints retained and removed byte counts for each cache, so this is the read that decides whether symbolicator.cleanup is worth running.","description":"Show what a cache cleanup would remove and what it would keep, per cache, without deleting anything. Symbolicator prints retained and removed byte counts for each cache, so this is the read that decides whether symbolicator.cleanup is worth running.","kind":"exec","risk":"low","side_effects":["Walks the caches to evaluate their retention, which is disk-read heavy on a large cache.","Deletes nothing.","Read-only."],"args":[],"examples":[{"title":"What would a cleanup reclaim?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ -f \"$config\" ]; then exec symbolicator cleanup --dry-run -c \"$config\"; else exec symbolicator cleanup --dry-run; fi"]}},{"id":"symbolicator.config_show","title":"Show symbolicator config.yml","summary":"Dump the Symbolicator configuration this host runs — cache root, retention windows, bind address, and the symbol sources. Reading it is how you explain why a cleanup reclaimed nothing or why a symbol never resolves. High risk on purpose: the sources block is operator-authored and routinely holds S3, GCS, or HTTP credentials, so the whole file is treated as secret-bearing rather than trusted to a pattern.","description":"Dump the Symbolicator configuration this host runs — cache root, retention windows, bind address, and the symbol sources. Reading it is how you explain why a cleanup reclaimed nothing or why a symbol never resolves. High risk on purpose: the sources block is operator-authored and routinely holds S3, GCS, or HTTP credentials, so the whole file is treated as secret-bearing rather than trusted to a pattern.","kind":"exec","risk":"high","side_effects":["Reads the configuration file and returns its contents.","Credential-shaped keys are masked on the way out, but the key space is the operator's, so a credential under a name we do not model would reach the caller.","Read-only."],"args":[],"examples":[{"title":"What configuration is this host running?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ ! -f \"$config\" ]; then printf 'no configuration at %s — the service is running on built-in defaults\\n' \"$config\" >&2; exit 1; fi; exec cat \"$config\""]}},{"id":"symbolicator.health","title":"GET /healthcheck","summary":"Check whether Symbolicator is serving on this host. Answers \"ok\" while the HTTP server is up; a connection error means the service is down or bound somewhere other than SYMBOLICATOR_URL.","description":"Check whether Symbolicator is serving on this host. Answers \"ok\" while the HTTP server is up; a connection error means the service is down or bound somewhere other than SYMBOLICATOR_URL.","kind":"exec","risk":"low","side_effects":["One HTTP GET to the local service.","Read-only."],"args":[],"examples":[{"title":"Is Symbolicator serving?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 10 \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/healthcheck\""]}},{"id":"symbolicator.request_status","title":"GET /requests/<id>","summary":"Show the status of one symbolication request by its id — whether it is still pending or has completed, and its result when it has. Use it when Sentry reports a symbolication that never came back. An unknown or expired id answers 404.","description":"Show the status of one symbolication request by its id — whether it is still pending or has completed, and its result when it has. Use it when Sentry reports a symbolication that never came back. An unknown or expired id answers 404.","kind":"exec","risk":"low","side_effects":["One HTTP GET to the local service.","Waits up to the requested timeout for a pending request to finish.","Read-only."],"args":[{"name":"request_id","type":"string","required":true,"description":"Request id Symbolicator returned when the symbolication was accepted.","validation":{"pattern":"^[A-Za-z0-9_-]{1,128}$","max_length":128}},{"name":"timeout_seconds","type":"integer","required":false,"default":0,"description":"Seconds to wait for a pending request before answering; 0 returns its current state.","validation":{"min":0,"max":60}}],"examples":[{"title":"Where did this symbolication get to?","args":{"request_id":"e5f2b7a1c0d34e1fa9b8c7d6e5f4a3b2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 90 \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/requests/$1?timeout=$2\"","emisar","{{ args.request_id }}","{{ args.timeout_seconds }}"]}},{"id":"symbolicator.symbolicate","title":"POST /symbolicate","summary":"Symbolicate a native stack trace — turn instruction addresses into function names, files, and line numbers using the debug files this Symbolicator already has access to. Send the crash's modules and frames; the symbols come from the sources the operator configured, never from the request.","description":"Symbolicate a native stack trace — turn instruction addresses into function names, files, and line numbers using the debug files this Symbolicator already has access to. Send the crash's modules and frames; the symbols come from the sources the operator configured, never from the request.","kind":"exec","risk":"low","side_effects":["Resolves against the configured symbol sources; a debug file not cached yet is downloaded from them, which costs bandwidth and fills the caches.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol.","Returns symbolicated frames, and source context when a source bundle covers them."],"args":[{"name":"payload","type":"string","required":true,"description":"JSON object with `modules` (each with type, debug_id, code_file, image_addr, image_size) and `stacktraces` (each with `frames` carrying instruction_addr). An `options` object is optional. Any other key, including `sources`, is dropped before the request is sent.","validation":{"max_length":262144}}],"examples":[{"title":"Resolve one frame in a Windows module","args":{"payload":"{\"modules\":[{\"type\":\"pe\",\"debug_id\":\"3249d99d-0c40-4931-8610-f4e4fb0b6936-1\",\"code_file\":\"C:\\\\Windows\\\\System32\\\\kernel32.dll\",\"image_addr\":\"0x749d0000\",\"image_size\":851968}],\"stacktraces\":[{\"registers\":{},\"frames\":[{\"instruction_addr\":\"0x749e8630\"}]}]}"}}],"search_terms":["resolve stack trace","crash addresses to function names"],"command":{"binary":"/bin/sh","argv":["-c","body=$(printf '%s' \"$1\" | jq -c '{options: (.options // {dif_candidates: true}), modules: (.modules // []), stacktraces: (.stacktraces // [])}') || { printf 'payload must be a JSON object with modules and stacktraces\\n' >&2; exit 2; }; printf '%s' \"$body\" | curl -fsS --globoff --proto \"=http,https\" --max-time 180 -H 'content-type: application/json' --data-binary @- \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/symbolicate\"","emisar","{{ args.payload }}"]}},{"id":"symbolicator.symbolicate_apple_crash","title":"POST /applecrashreport","summary":"Symbolicate an Apple crash report already on this host — the iOS or macOS .crash text a device produced — against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","description":"Symbolicate an Apple crash report already on this host — the iOS or macOS .crash text a device produced — against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","kind":"exec","risk":"low","side_effects":["Reads the named report and sends its contents to the local symbolication service.","Resolves against the configured symbol sources; a dSYM not cached yet is downloaded from them.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol."],"args":[{"name":"path","type":"string","required":true,"description":"Apple crash report file on this host.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/var/lib/systemd/coredump","/var/crash","/var/tmp","/tmp","/data"],"max_length":512}}],"examples":[{"title":"Symbolicate a report pulled off a device","args":{"path":"/var/tmp/MyApp-2026-08-12-100731.crash"}}],"search_terms":["ios crash","macos crash report","dsym"],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 300 -F \"apple_crash_report=@$1\" \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/applecrashreport\"","emisar","{{ args.path }}"]}},{"id":"symbolicator.symbolicate_minidump","title":"POST /minidump","summary":"Symbolicate a minidump already on this host — the crashing thread, its stack, and the loaded modules, resolved against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","description":"Symbolicate a minidump already on this host — the crashing thread, its stack, and the loaded modules, resolved against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","kind":"exec","risk":"low","side_effects":["Reads the named dump and sends its bytes to the local symbolication service.","Resolves against the configured symbol sources; a debug file not cached yet is downloaded from them.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol."],"args":[{"name":"path","type":"string","required":true,"description":"Minidump file on this host.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/var/lib/systemd/coredump","/var/crash","/var/tmp","/tmp","/data"],"max_length":512}}],"examples":[{"title":"Symbolicate a dump systemd-coredump kept","args":{"path":"/var/lib/systemd/coredump/core.myapp.1000.dmp"}}],"search_terms":["crash dump","core dump symbolication"],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 300 -F \"upload_file_minidump=@$1\" \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/minidump\"","emisar","{{ args.path }}"]}},{"id":"symbolicator.version","title":"symbolicator --version","summary":"Show the Symbolicator build installed on this host — release version and git commit. Reports the binary on disk, which is what a restart would start.","description":"Show the Symbolicator build installed on this host — release version and git commit. Reports the binary on disk, which is what a restart would start.","kind":"exec","risk":"low","side_effects":["Reads the binary's build information.","Read-only."],"args":[],"examples":[{"title":"Installed build","args":{}}],"search_terms":[],"command":{"binary":"symbolicator","argv":["--version"]}}]},{"version":"0.2.0","content_hash":"sha256:a122dce646e6bdeb81aa5513436a8cf7b9a99bfbbd477dbc6cf9e96aef1b869e","tarball_url":"https://registry.emisar.dev/v1/packs/symbolicator/0.2.0/a122dce646e6bdeb81aa5513436a8cf7b9a99bfbbd477dbc6cf9e96aef1b869e/pack.tar.gz","actions":[{"id":"symbolicator.cache_usage","title":"Symbolicator cache footprint","summary":"Show how much disk each Symbolicator cache holds, largest first, with the filesystem underneath it. The caches — objects, symcaches, cficaches and the rest — are what fills a symbolication host, and they grow at very different rates, so this is the read to take before deciding whether a cleanup is the answer.","description":"Show how much disk each Symbolicator cache holds, largest first, with the filesystem underneath it. The caches — objects, symcaches, cficaches and the rest — are what fills a symbolication host, and they grow at very different rates, so this is the read to take before deciding whether a cleanup is the answer.","kind":"script","risk":"low","side_effects":["Walks the cache directories to size them, which is disk-read heavy on a large cache.","Reads filesystem metadata only.","Read-only."],"args":[],"examples":[{"title":"Which cache is eating the disk?","args":{}}],"search_terms":["disk full","symbol cache size"]},{"id":"symbolicator.cleanup","title":"symbolicator cleanup","summary":"Delete the cache entries that have gone unused past their configured retention, reclaiming disk. This is Symbolicator's own routine maintenance, bounded by the retention windows in its configuration — not a wipe. Preview it with symbolicator.cleanup_preview first.","description":"Delete the cache entries that have gone unused past their configured retention, reclaiming disk. This is Symbolicator's own routine maintenance, bounded by the retention windows in its configuration — not a wipe. Preview it with symbolicator.cleanup_preview first.","kind":"exec","risk":"medium","side_effects":["Removes cached debug files and derived caches whose retention has expired; a later symbolication that needs one re-downloads it from the configured symbol sources.","Symbolication is slower until the working set is cached again, and the re-download costs bandwidth against those sources.","Runs while the service serves; it does not restart or interrupt Symbolicator.","Reclaims nothing when the caches are within retention, which is what the preview reports."],"args":[],"examples":[{"title":"Reclaim expired cache entries","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ -f \"$config\" ]; then exec symbolicator cleanup -c \"$config\"; else exec symbolicator cleanup; fi"]}},{"id":"symbolicator.cleanup_preview","title":"symbolicator cleanup --dry-run","summary":"Show what a cache cleanup would remove and what it would keep, per cache, without deleting anything. Symbolicator prints retained and removed byte counts for each cache, so this is the read that decides whether symbolicator.cleanup is worth running.","description":"Show what a cache cleanup would remove and what it would keep, per cache, without deleting anything. Symbolicator prints retained and removed byte counts for each cache, so this is the read that decides whether symbolicator.cleanup is worth running.","kind":"exec","risk":"low","side_effects":["Walks the caches to evaluate their retention, which is disk-read heavy on a large cache.","Deletes nothing.","Read-only."],"args":[],"examples":[{"title":"What would a cleanup reclaim?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ -f \"$config\" ]; then exec symbolicator cleanup --dry-run -c \"$config\"; else exec symbolicator cleanup --dry-run; fi"]}},{"id":"symbolicator.config_show","title":"Show symbolicator config.yml","summary":"Dump the Symbolicator configuration this host runs — cache root, retention windows, bind address, and the symbol sources. Reading it is how you explain why a cleanup reclaimed nothing or why a symbol never resolves. High risk on purpose: the sources block is operator-authored and routinely holds S3, GCS, or HTTP credentials, so the whole file is treated as secret-bearing rather than trusted to a pattern.","description":"Dump the Symbolicator configuration this host runs — cache root, retention windows, bind address, and the symbol sources. Reading it is how you explain why a cleanup reclaimed nothing or why a symbol never resolves. High risk on purpose: the sources block is operator-authored and routinely holds S3, GCS, or HTTP credentials, so the whole file is treated as secret-bearing rather than trusted to a pattern.","kind":"exec","risk":"high","side_effects":["Reads the configuration file and returns its contents.","Credential-shaped keys are masked on the way out, but the key space is the operator's, so a credential under a name we do not model would reach the caller.","Read-only."],"args":[],"examples":[{"title":"What configuration is this host running?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","config=\"${SYMBOLICATOR_CONFIG:-/etc/symbolicator/config.yml}\"; if [ ! -f \"$config\" ]; then printf 'no configuration at %s — the service is running on built-in defaults\\n' \"$config\" >&2; exit 1; fi; exec cat \"$config\""]}},{"id":"symbolicator.health","title":"GET /healthcheck","summary":"Check whether Symbolicator is serving on this host. Answers \"ok\" while the HTTP server is up; a connection error means the service is down or bound somewhere other than SYMBOLICATOR_URL.","description":"Check whether Symbolicator is serving on this host. Answers \"ok\" while the HTTP server is up; a connection error means the service is down or bound somewhere other than SYMBOLICATOR_URL.","kind":"exec","risk":"low","side_effects":["One HTTP GET to the local service.","Read-only."],"args":[],"examples":[{"title":"Is Symbolicator serving?","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 10 \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/healthcheck\""]}},{"id":"symbolicator.request_status","title":"GET /requests/<id>","summary":"Show the status of one symbolication request by its id — whether it is still pending or has completed, and its result when it has. Use it when Sentry reports a symbolication that never came back. An unknown or expired id answers 404.","description":"Show the status of one symbolication request by its id — whether it is still pending or has completed, and its result when it has. Use it when Sentry reports a symbolication that never came back. An unknown or expired id answers 404.","kind":"exec","risk":"low","side_effects":["One HTTP GET to the local service.","Waits up to the requested timeout for a pending request to finish.","Read-only."],"args":[{"name":"request_id","type":"string","required":true,"description":"Request id Symbolicator returned when the symbolication was accepted.","validation":{"pattern":"^[A-Za-z0-9_-]{1,128}$","max_length":128}},{"name":"timeout_seconds","type":"integer","required":false,"default":0,"description":"Seconds to wait for a pending request before answering; 0 returns its current state.","validation":{"min":0,"max":60}}],"examples":[{"title":"Where did this symbolication get to?","args":{"request_id":"e5f2b7a1c0d34e1fa9b8c7d6e5f4a3b2"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 90 \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/requests/$1?timeout=$2\"","emisar","{{ args.request_id }}","{{ args.timeout_seconds }}"]}},{"id":"symbolicator.symbolicate","title":"POST /symbolicate","summary":"Symbolicate a native stack trace — turn instruction addresses into function names, files, and line numbers using the debug files this Symbolicator already has access to. Send the crash's modules and frames; the symbols come from the sources the operator configured, never from the request.","description":"Symbolicate a native stack trace — turn instruction addresses into function names, files, and line numbers using the debug files this Symbolicator already has access to. Send the crash's modules and frames; the symbols come from the sources the operator configured, never from the request.","kind":"exec","risk":"low","side_effects":["Resolves against the configured symbol sources; a debug file not cached yet is downloaded from them, which costs bandwidth and fills the caches.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol.","Returns symbolicated frames, and source context when a source bundle covers them."],"args":[{"name":"payload","type":"string","required":true,"description":"JSON object with `modules` (each with type, debug_id, code_file, image_addr, image_size) and `stacktraces` (each with `frames` carrying instruction_addr). An `options` object is optional. Any other key, including `sources`, is dropped before the request is sent.","validation":{"max_length":262144}}],"examples":[{"title":"Resolve one frame in a Windows module","args":{"payload":"{\"modules\":[{\"type\":\"pe\",\"debug_id\":\"3249d99d-0c40-4931-8610-f4e4fb0b6936-1\",\"code_file\":\"C:\\\\Windows\\\\System32\\\\kernel32.dll\",\"image_addr\":\"0x749d0000\",\"image_size\":851968}],\"stacktraces\":[{\"registers\":{},\"frames\":[{\"instruction_addr\":\"0x749e8630\"}]}]}"}}],"search_terms":["resolve stack trace","crash addresses to function names"],"command":{"binary":"/bin/sh","argv":["-c","body=$(printf '%s' \"$1\" | jq -c '{options: (.options // {dif_candidates: true}), modules: (.modules // []), stacktraces: (.stacktraces // [])}') || { printf 'payload must be a JSON object with modules and stacktraces\\n' >&2; exit 2; }; printf '%s' \"$body\" | curl -fsS --globoff --proto \"=http,https\" --max-time 180 -H 'content-type: application/json' --data-binary @- \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/symbolicate\"","emisar","{{ args.payload }}"]}},{"id":"symbolicator.symbolicate_apple_crash","title":"POST /applecrashreport","summary":"Symbolicate an Apple crash report already on this host — the iOS or macOS .crash text a device produced — against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","description":"Symbolicate an Apple crash report already on this host — the iOS or macOS .crash text a device produced — against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","kind":"exec","risk":"low","side_effects":["Reads the named report and sends its contents to the local symbolication service.","Resolves against the configured symbol sources; a dSYM not cached yet is downloaded from them.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol."],"args":[{"name":"path","type":"string","required":true,"description":"Apple crash report file on this host.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/var/lib/systemd/coredump","/var/crash","/var/tmp","/tmp","/data"],"max_length":512}}],"examples":[{"title":"Symbolicate a report pulled off a device","args":{"path":"/var/tmp/MyApp-2026-08-12-100731.crash"}}],"search_terms":["ios crash","macos crash report","dsym"],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 300 -F \"apple_crash_report=@$1\" \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/applecrashreport\"","emisar","{{ args.path }}"]}},{"id":"symbolicator.symbolicate_minidump","title":"POST /minidump","summary":"Symbolicate a minidump already on this host — the crashing thread, its stack, and the loaded modules, resolved against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","description":"Symbolicate a minidump already on this host — the crashing thread, its stack, and the loaded modules, resolved against the debug files this Symbolicator has access to. Answers with the symbolicated result, or with a request id to follow using symbolicator.request_status when the work runs long.","kind":"exec","risk":"low","side_effects":["Reads the named dump and sends its bytes to the local symbolication service.","Resolves against the configured symbol sources; a debug file not cached yet is downloaded from them.","Adds nothing to those sources — Symbolicator has no ingest path, so nothing here can publish, alter, or delete a symbol."],"args":[{"name":"path","type":"string","required":true,"description":"Minidump file on this host.","validation":{"pattern":"^/[a-zA-Z0-9_./\\-]{1,512}$","allowed_prefixes":["/var/lib/systemd/coredump","/var/crash","/var/tmp","/tmp","/data"],"max_length":512}}],"examples":[{"title":"Symbolicate a dump systemd-coredump kept","args":{"path":"/var/lib/systemd/coredump/core.myapp.1000.dmp"}}],"search_terms":["crash dump","core dump symbolication"],"command":{"binary":"/bin/sh","argv":["-c","exec curl -fsS --globoff --proto \"=http,https\" --max-time 300 -F \"upload_file_minidump=@$1\" \"${SYMBOLICATOR_URL:-http://127.0.0.1:3021}/minidump\"","emisar","{{ args.path }}"]}},{"id":"symbolicator.version","title":"symbolicator --version","summary":"Show the Symbolicator build installed on this host — release version and git commit. Reports the binary on disk, which is what a restart would start.","description":"Show the Symbolicator build installed on this host — release version and git commit. Reports the binary on disk, which is what a restart would start.","kind":"exec","risk":"low","side_effects":["Reads the binary's build information.","Read-only."],"args":[],"examples":[{"title":"Installed build","args":{}}],"search_terms":[],"command":{"binary":"symbolicator","argv":["--version"]}}]}]},{"id":"systemd-deep","name":"Systemd deep introspection pack","version":"0.1.19","description":"Deeper systemd state than linux-core: failed units, list-units, timers, cgroup tree, journal disk usage, systemd-analyze for boot diagnosis, plus full operator surface (daemon-reload, start/stop/ restart/reload, kill -s signal, mask/unmask, reset-failed) for remediating runtime issues.","vendor":"emisar","homepage":"https://emisar.dev/packs/systemd-deep","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/systemd-deep","content_hash":"sha256:e3a93a2dcd44debd457671a85c676d8e238db43028b5f2861808b1655bb950a1","tarball_url":"https://registry.emisar.dev/v1/packs/systemd-deep/0.1.19/e3a93a2dcd44debd457671a85c676d8e238db43028b5f2861808b1655bb950a1/pack.tar.gz","requires":{"os":["linux"],"binaries":["systemctl"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the local runner host — no credentials needed.","notes":["Most introspection (failed_units, list_units, timers, cgroup_tree, analyze_*, unit_show) is read-only and needs no privilege."],"host_access":[{"actions":["systemd.boot_errors"],"requirement":"Read the complete system journal.","recipes":[{"name":"Add the Emisar service user to systemd-journal","commands":["sudo usermod -aG systemd-journal emisar","sudo systemctl restart emisar"],"verify":["id -nG emisar | tr ' ' '\\n' | grep -Fx systemd-journal","sudo -u emisar journalctl -b -n 1 --no-pager >/dev/null"],"impact":"Every process running as emisar can read the full system journal, which may contain application output, usernames, addresses, and secrets written by services."}]},{"actions":["systemd.vacuum_journal","systemd.daemon_reload","systemd.unit_start","systemd.unit_stop","systemd.unit_restart","systemd.unit_reload","systemd.unit_kill","systemd.unit_mask","systemd.unit_unmask","systemd.reset_failed"],"requirement":"Change arbitrary systemd units and journal retention as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-systemd-deep-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. These actions can stop, mask, kill, or reconfigure any systemd unit and permanently delete journal history."}]}],"verify":"systemd.failed_units"},"actions":[{"id":"systemd.analyze_blame","title":"systemd-analyze blame","summary":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","description":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[],"examples":[{"title":"Slowest 30 units","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(systemd-analyze blame 2>&1); status=$?; printf '%s\\n' \"$out\" | head -30; exit $status"]}},{"id":"systemd.analyze_critical_chain","title":"systemd-analyze critical-chain","summary":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","description":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to analyze.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Boot path for multi-user","args":{"unit":"multi-user.target"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemd-analyze critical-chain \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.analyze_security","title":"systemd-analyze security","summary":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","description":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to audit.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Audit nginx sandboxing","args":{"unit":"nginx.service"}}],"search_terms":["hardening","exposure"],"command":{"binary":"systemd-analyze","argv":["security","{{ args.unit }}"]}},{"id":"systemd.boot_errors","title":"Boot-time journal errors","summary":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","description":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","kind":"exec","risk":"medium","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Boot errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -b -p err --no-pager | tail -100"]}},{"id":"systemd.cgroup_top","title":"systemd-cgtop (3 samples)","summary":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","description":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","kind":"exec","risk":"low","side_effects":["One systemd-cgtop invocation lasting ~3s.","Read-only."],"args":[],"examples":[{"title":"cgtop snapshot","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgtop","argv":["-b","-n","3"]}},{"id":"systemd.cgroup_tree","title":"systemd cgroup tree","summary":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","description":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","kind":"exec","risk":"low","side_effects":["One systemd-cgls invocation.","Read-only."],"args":[],"examples":[{"title":"cgroup hierarchy","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgls","argv":["--no-pager"]}},{"id":"systemd.daemon_reload","title":"systemctl daemon-reload","summary":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","description":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","kind":"exec","risk":"medium","side_effects":["systemd re-reads all unit files.","Running units unaffected; their definitions update on next restart."],"args":[],"examples":[{"title":"Pick up unit file changes","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["daemon-reload"]}},{"id":"systemd.failed_units","title":"Failed systemd units","summary":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","description":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"Anything failed?","args":{}}],"search_terms":["service failing","keeps crashing","crashed"],"command":{"binary":"systemctl","argv":["--failed","--no-pager","--no-legend"]}},{"id":"systemd.journal_disk_usage","title":"journalctl --disk-usage","summary":"Show how much disk the systemd journal is using.","description":"Show how much disk the systemd journal is using.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Journal disk usage","args":{}}],"search_terms":["journal size"],"command":{"binary":"journalctl","argv":["--disk-usage"]}},{"id":"systemd.list_unit_files","title":"List installed unit files","summary":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","description":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All unit files + enable state","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-unit-files","--type=service","--no-pager","--no-legend"]}},{"id":"systemd.list_units","title":"List all systemd units","summary":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","description":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-units","--type=service","--all","--no-pager","--no-legend"]}},{"id":"systemd.reset_failed","title":"systemctl reset-failed [unit]","summary":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","description":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","kind":"exec","risk":"medium","side_effects":["Failed-state flag cleared.","Start-limit counter reset.","Unit not started — explicit start still needed if desired."],"args":[{"name":"unit","type":"string","required":false,"default":"","description":"Unit name (empty for all failed units).","validation":{"pattern":"^([a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127})?$"}}],"examples":[{"title":"Reset all failed","args":{}},{"title":"Reset one unit","args":{"unit":"myapp.service"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl reset-failed \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.sockets","title":"systemd-managed sockets","summary":"`systemctl list-sockets` — every socket-activated unit with its listening address.","description":"`systemctl list-sockets` — every socket-activated unit with its listening address.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All sockets","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-sockets","--no-pager","--no-legend"]}},{"id":"systemd.timers","title":"Active systemd timers","summary":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","description":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All timers","args":{}}],"search_terms":["scheduled jobs"],"command":{"binary":"systemctl","argv":["list-timers","--all","--no-pager","--no-legend"]}},{"id":"systemd.unit_kill","title":"systemctl kill -s <signal> <unit>","summary":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","description":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","kind":"exec","risk":"high","side_effects":["Signal sent to the unit.","Behavior depends on signal — SIGHUP often triggers config reload."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGKILL","SIGHUP","SIGUSR1","SIGUSR2","SIGINT","SIGQUIT"]}}],"examples":[{"title":"Send SIGHUP for config reload","args":{"signal":"SIGHUP","unit":"rsyslog.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["kill","-s","{{ args.signal }}","{{ args.unit }}"]}},{"id":"systemd.unit_mask","title":"systemctl mask <unit>","summary":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","description":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","kind":"exec","risk":"high","side_effects":["Unit cannot be started until unmasked.","Dependency chains referencing this unit may fail to activate."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Mask a noisy service","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["mask","{{ args.unit }}"]}},{"id":"systemd.unit_reload","title":"systemctl reload <unit>","summary":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","description":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","kind":"exec","risk":"high","side_effects":["Unit re-reads its config.","Process keeps running; PID unchanged.","In-flight requests survive."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Reload nginx without restart","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"systemd.unit_restart","title":"systemctl restart <unit>","summary":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","description":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","kind":"exec","risk":"high","side_effects":["Service stopped then started.","In-flight requests/connections terminated mid-restart.","PID changes; any reverse-proxy or supervisor must re-resolve."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name (e.g., nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Restart nginx","args":{"unit":"nginx.service"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"systemd.unit_show","title":"systemctl show <unit>","summary":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One systemctl invocation.","Read-only, but exposes the unit's Environment= values and ExecStart (may include secrets)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Full nginx properties","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["show","{{ args.unit }}","--no-pager"]}},{"id":"systemd.unit_start","title":"systemctl start <unit>","summary":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","description":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","kind":"exec","risk":"high","side_effects":["Service started, along with any units it requires.","Triggers the unit's ExecStartPre/ExecStartPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Start a unit","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","{{ args.unit }}"]}},{"id":"systemd.unit_stop","title":"systemctl stop <unit>","summary":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","description":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","kind":"exec","risk":"high","side_effects":["Service stopped.","In-flight work terminated.","Stays stopped until started again (or Restart= triggers)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Stop a misbehaving worker","args":{"unit":"stuck-worker.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","{{ args.unit }}"]}},{"id":"systemd.unit_unmask","title":"systemctl unmask <unit>","summary":"Undo `mask` for one unit. The unit can be started again.","description":"Undo `mask` for one unit. The unit can be started again.","kind":"exec","risk":"medium","side_effects":["Unit no longer masked.","Unit not started — explicit start still needed."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Unmask a unit","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["unmask","{{ args.unit }}"]}},{"id":"systemd.vacuum_journal","title":"Vacuum the systemd journal","summary":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","description":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","kind":"exec","risk":"high","side_effects":["Deletes journal records older than the cutoff.","Frees disk under /var/log/journal."],"args":[{"name":"cutoff","type":"string","required":true,"description":"Vacuum window (e.g. \"7d\", \"30d\", \"12h\").","validation":{"pattern":"^[0-9]{1,4}[smhdw]$"}}],"examples":[{"title":"Keep last 7 days","args":{"cutoff":"7d"}}],"search_terms":["shrink journal","reclaim disk space"],"command":{"binary":"journalctl","argv":["--vacuum-time={{ args.cutoff }}"]}},{"id":"systemd.watchdog_status","title":"Watchdog status across units","summary":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","description":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","kind":"exec","risk":"low","side_effects":["Iterates systemctl show across all units.","Read-only."],"args":[],"examples":[{"title":"Units with watchdog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl list-units --type=service --plain --no-legend --no-pager | awk '{print $1}' | while read u; do v=$(systemctl show \"$u\" -p WatchdogUSec --value 2>/dev/null); if [ -n \"$v\" ] && [ \"$v\" != \"0\" ]; then echo \"$u: $v\"; fi; done"]}}],"previous_versions":[{"version":"0.1.16","content_hash":"sha256:f96d72b717c708eff69e7f72e7e409bc113a894d112c3931bdba1ae756d07715","tarball_url":"https://registry.emisar.dev/v1/packs/systemd-deep/0.1.16/f96d72b717c708eff69e7f72e7e409bc113a894d112c3931bdba1ae756d07715/pack.tar.gz","actions":[{"id":"systemd.analyze_blame","title":"systemd-analyze blame","summary":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","description":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[],"examples":[{"title":"Slowest 30 units","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(systemd-analyze blame 2>&1); status=$?; printf '%s\\n' \"$out\" | head -30; exit $status"]}},{"id":"systemd.analyze_critical_chain","title":"systemd-analyze critical-chain","summary":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","description":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to analyze.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Boot path for multi-user","args":{"unit":"multi-user.target"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemd-analyze critical-chain \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.analyze_security","title":"systemd-analyze security","summary":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","description":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to audit.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Audit nginx sandboxing","args":{"unit":"nginx.service"}}],"search_terms":["hardening","exposure"],"command":{"binary":"systemd-analyze","argv":["security","{{ args.unit }}"]}},{"id":"systemd.boot_errors","title":"Boot-time journal errors","summary":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","description":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Boot errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -b -p err --no-pager | tail -100"]}},{"id":"systemd.cgroup_top","title":"systemd-cgtop (3 samples)","summary":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","description":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","kind":"exec","risk":"low","side_effects":["One systemd-cgtop invocation lasting ~3s.","Read-only."],"args":[],"examples":[{"title":"cgtop snapshot","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgtop","argv":["-b","-n","3"]}},{"id":"systemd.cgroup_tree","title":"systemd cgroup tree","summary":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","description":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","kind":"exec","risk":"low","side_effects":["One systemd-cgls invocation.","Read-only."],"args":[],"examples":[{"title":"cgroup hierarchy","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgls","argv":["--no-pager"]}},{"id":"systemd.daemon_reload","title":"systemctl daemon-reload","summary":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","description":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","kind":"exec","risk":"medium","side_effects":["systemd re-reads all unit files.","Running units unaffected; their definitions update on next restart."],"args":[],"examples":[{"title":"Pick up unit file changes","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["daemon-reload"]}},{"id":"systemd.failed_units","title":"Failed systemd units","summary":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","description":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"Anything failed?","args":{}}],"search_terms":["service failing","keeps crashing","crashed"],"command":{"binary":"systemctl","argv":["--failed","--no-pager","--no-legend"]}},{"id":"systemd.journal_disk_usage","title":"journalctl --disk-usage","summary":"Show how much disk the systemd journal is using.","description":"Show how much disk the systemd journal is using.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Journal disk usage","args":{}}],"search_terms":["journal size"],"command":{"binary":"journalctl","argv":["--disk-usage"]}},{"id":"systemd.list_unit_files","title":"List installed unit files","summary":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","description":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All unit files + enable state","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-unit-files","--type=service","--no-pager","--no-legend"]}},{"id":"systemd.list_units","title":"List all systemd units","summary":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","description":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-units","--type=service","--all","--no-pager","--no-legend"]}},{"id":"systemd.reset_failed","title":"systemctl reset-failed [unit]","summary":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","description":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","kind":"exec","risk":"medium","side_effects":["Failed-state flag cleared.","Start-limit counter reset.","Unit not started — explicit start still needed if desired."],"args":[{"name":"unit","type":"string","required":false,"default":"","description":"Unit name (empty for all failed units).","validation":{"pattern":"^([a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127})?$"}}],"examples":[{"title":"Reset all failed","args":{}},{"title":"Reset one unit","args":{"unit":"myapp.service"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl reset-failed \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.sockets","title":"systemd-managed sockets","summary":"`systemctl list-sockets` — every socket-activated unit with its listening address.","description":"`systemctl list-sockets` — every socket-activated unit with its listening address.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All sockets","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-sockets","--no-pager","--no-legend"]}},{"id":"systemd.timers","title":"Active systemd timers","summary":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","description":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All timers","args":{}}],"search_terms":["scheduled jobs"],"command":{"binary":"systemctl","argv":["list-timers","--all","--no-pager","--no-legend"]}},{"id":"systemd.unit_kill","title":"systemctl kill -s <signal> <unit>","summary":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","description":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","kind":"exec","risk":"high","side_effects":["Signal sent to the unit.","Behavior depends on signal — SIGHUP often triggers config reload."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGKILL","SIGHUP","SIGUSR1","SIGUSR2","SIGINT","SIGQUIT"]}}],"examples":[{"title":"Send SIGHUP for config reload","args":{"signal":"SIGHUP","unit":"rsyslog.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["kill","-s","{{ args.signal }}","{{ args.unit }}"]}},{"id":"systemd.unit_mask","title":"systemctl mask <unit>","summary":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","description":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","kind":"exec","risk":"high","side_effects":["Unit cannot be started until unmasked.","Dependency chains referencing this unit may fail to activate."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Mask a noisy service","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["mask","{{ args.unit }}"]}},{"id":"systemd.unit_reload","title":"systemctl reload <unit>","summary":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","description":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","kind":"exec","risk":"high","side_effects":["Unit re-reads its config.","Process keeps running; PID unchanged.","In-flight requests survive."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Reload nginx without restart","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"systemd.unit_restart","title":"systemctl restart <unit>","summary":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","description":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","kind":"exec","risk":"high","side_effects":["Service stopped then started.","In-flight requests/connections terminated mid-restart.","PID changes; any reverse-proxy or supervisor must re-resolve."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name (e.g., nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Restart nginx","args":{"unit":"nginx.service"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"systemd.unit_show","title":"systemctl show <unit>","summary":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One systemctl invocation.","Read-only, but exposes the unit's Environment= values and ExecStart (may include secrets)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Full nginx properties","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["show","{{ args.unit }}","--no-pager"]}},{"id":"systemd.unit_start","title":"systemctl start <unit>","summary":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","description":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","kind":"exec","risk":"high","side_effects":["Service started, along with any units it requires.","Triggers the unit's ExecStartPre/ExecStartPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Start a unit","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","{{ args.unit }}"]}},{"id":"systemd.unit_stop","title":"systemctl stop <unit>","summary":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","description":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","kind":"exec","risk":"high","side_effects":["Service stopped.","In-flight work terminated.","Stays stopped until started again (or Restart= triggers)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Stop a misbehaving worker","args":{"unit":"stuck-worker.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","{{ args.unit }}"]}},{"id":"systemd.unit_unmask","title":"systemctl unmask <unit>","summary":"Undo `mask` for one unit. The unit can be started again.","description":"Undo `mask` for one unit. The unit can be started again.","kind":"exec","risk":"medium","side_effects":["Unit no longer masked.","Unit not started — explicit start still needed."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Unmask a unit","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["unmask","{{ args.unit }}"]}},{"id":"systemd.vacuum_journal","title":"Vacuum the systemd journal","summary":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","description":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","kind":"exec","risk":"high","side_effects":["Deletes journal records older than the cutoff.","Frees disk under /var/log/journal."],"args":[{"name":"cutoff","type":"string","required":true,"description":"Vacuum window (e.g. \"7d\", \"30d\", \"12h\").","validation":{"pattern":"^[0-9]{1,4}[smhdw]$"}}],"examples":[{"title":"Keep last 7 days","args":{"cutoff":"7d"}}],"search_terms":["shrink journal","reclaim disk space"],"command":{"binary":"journalctl","argv":["--vacuum-time={{ args.cutoff }}"]}},{"id":"systemd.watchdog_status","title":"Watchdog status across units","summary":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","description":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","kind":"exec","risk":"low","side_effects":["Iterates systemctl show across all units.","Read-only."],"args":[],"examples":[{"title":"Units with watchdog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl list-units --type=service --plain --no-legend --no-pager | awk '{print $1}' | while read u; do v=$(systemctl show \"$u\" -p WatchdogUSec --value 2>/dev/null); if [ -n \"$v\" ] && [ \"$v\" != \"0\" ]; then echo \"$u: $v\"; fi; done"]}}]},{"version":"0.1.15","content_hash":"sha256:a39bcb7a8172275a5870bf1e69ee4c13b7289f36312a66778d231368e9afdfcd","tarball_url":"https://registry.emisar.dev/v1/packs/systemd-deep/0.1.15/a39bcb7a8172275a5870bf1e69ee4c13b7289f36312a66778d231368e9afdfcd/pack.tar.gz","actions":[{"id":"systemd.analyze_blame","title":"systemd-analyze blame","summary":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","description":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[],"examples":[{"title":"Slowest 30 units","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(systemd-analyze blame 2>&1); status=$?; printf '%s\\n' \"$out\" | head -30; exit $status"]}},{"id":"systemd.analyze_critical_chain","title":"systemd-analyze critical-chain","summary":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","description":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to analyze.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Boot path for multi-user","args":{"unit":"multi-user.target"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemd-analyze critical-chain \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.analyze_security","title":"systemd-analyze security","summary":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","description":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to audit.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Audit nginx sandboxing","args":{"unit":"nginx.service"}}],"search_terms":["hardening","exposure"],"command":{"binary":"systemd-analyze","argv":["security","{{ args.unit }}"]}},{"id":"systemd.boot_errors","title":"Boot-time journal errors","summary":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","description":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Boot errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -b -p err --no-pager | tail -100"]}},{"id":"systemd.cgroup_top","title":"systemd-cgtop (3 samples)","summary":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","description":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","kind":"exec","risk":"low","side_effects":["One systemd-cgtop invocation lasting ~3s.","Read-only."],"args":[],"examples":[{"title":"cgtop snapshot","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgtop","argv":["-b","-n","3"]}},{"id":"systemd.cgroup_tree","title":"systemd cgroup tree","summary":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","description":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","kind":"exec","risk":"low","side_effects":["One systemd-cgls invocation.","Read-only."],"args":[],"examples":[{"title":"cgroup hierarchy","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgls","argv":["--no-pager"]}},{"id":"systemd.daemon_reload","title":"systemctl daemon-reload","summary":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","description":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","kind":"exec","risk":"medium","side_effects":["systemd re-reads all unit files.","Running units unaffected; their definitions update on next restart."],"args":[],"examples":[{"title":"Pick up unit file changes","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["daemon-reload"]}},{"id":"systemd.failed_units","title":"Failed systemd units","summary":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","description":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"Anything failed?","args":{}}],"search_terms":["service failing","keeps crashing","crashed"],"command":{"binary":"systemctl","argv":["--failed","--no-pager","--no-legend"]}},{"id":"systemd.journal_disk_usage","title":"journalctl --disk-usage","summary":"Show how much disk the systemd journal is using.","description":"Show how much disk the systemd journal is using.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Journal disk usage","args":{}}],"search_terms":["journal size"],"command":{"binary":"journalctl","argv":["--disk-usage"]}},{"id":"systemd.list_unit_files","title":"List installed unit files","summary":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","description":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All unit files + enable state","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-unit-files","--type=service","--no-pager","--no-legend"]}},{"id":"systemd.list_units","title":"List all systemd units","summary":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","description":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-units","--type=service","--all","--no-pager","--no-legend"]}},{"id":"systemd.reset_failed","title":"systemctl reset-failed [unit]","summary":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","description":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","kind":"exec","risk":"medium","side_effects":["Failed-state flag cleared.","Start-limit counter reset.","Unit not started — explicit start still needed if desired."],"args":[{"name":"unit","type":"string","required":false,"default":"","description":"Unit name (empty for all failed units).","validation":{"pattern":"^([a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127})?$"}}],"examples":[{"title":"Reset all failed","args":{}},{"title":"Reset one unit","args":{"unit":"myapp.service"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl reset-failed \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.sockets","title":"systemd-managed sockets","summary":"`systemctl list-sockets` — every socket-activated unit with its listening address.","description":"`systemctl list-sockets` — every socket-activated unit with its listening address.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All sockets","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-sockets","--no-pager","--no-legend"]}},{"id":"systemd.timers","title":"Active systemd timers","summary":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","description":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All timers","args":{}}],"search_terms":["scheduled jobs"],"command":{"binary":"systemctl","argv":["list-timers","--all","--no-pager","--no-legend"]}},{"id":"systemd.unit_kill","title":"systemctl kill -s <signal> <unit>","summary":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","description":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","kind":"exec","risk":"high","side_effects":["Signal sent to the unit.","Behavior depends on signal — SIGHUP often triggers config reload."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGKILL","SIGHUP","SIGUSR1","SIGUSR2","SIGINT","SIGQUIT"]}}],"examples":[{"title":"Send SIGHUP for config reload","args":{"signal":"SIGHUP","unit":"rsyslog.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["kill","-s","{{ args.signal }}","{{ args.unit }}"]}},{"id":"systemd.unit_mask","title":"systemctl mask <unit>","summary":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","description":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","kind":"exec","risk":"high","side_effects":["Unit cannot be started until unmasked.","Dependency chains referencing this unit may fail to activate."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Mask a noisy service","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["mask","{{ args.unit }}"]}},{"id":"systemd.unit_reload","title":"systemctl reload <unit>","summary":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","description":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","kind":"exec","risk":"high","side_effects":["Unit re-reads its config.","Process keeps running; PID unchanged.","In-flight requests survive."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Reload nginx without restart","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"systemd.unit_restart","title":"systemctl restart <unit>","summary":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","description":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","kind":"exec","risk":"high","side_effects":["Service stopped then started.","In-flight requests/connections terminated mid-restart.","PID changes; any reverse-proxy or supervisor must re-resolve."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name (e.g., nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Restart nginx","args":{"unit":"nginx.service"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"systemd.unit_show","title":"systemctl show <unit>","summary":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One systemctl invocation.","Read-only, but exposes the unit's Environment= values and ExecStart (may include secrets)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Full nginx properties","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["show","{{ args.unit }}","--no-pager"]}},{"id":"systemd.unit_start","title":"systemctl start <unit>","summary":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","description":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","kind":"exec","risk":"high","side_effects":["Service started, along with any units it requires.","Triggers the unit's ExecStartPre/ExecStartPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Start a unit","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","{{ args.unit }}"]}},{"id":"systemd.unit_stop","title":"systemctl stop <unit>","summary":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","description":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","kind":"exec","risk":"high","side_effects":["Service stopped.","In-flight work terminated.","Stays stopped until started again (or Restart= triggers)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Stop a misbehaving worker","args":{"unit":"stuck-worker.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","{{ args.unit }}"]}},{"id":"systemd.unit_unmask","title":"systemctl unmask <unit>","summary":"Undo `mask` for one unit. The unit can be started again.","description":"Undo `mask` for one unit. The unit can be started again.","kind":"exec","risk":"medium","side_effects":["Unit no longer masked.","Unit not started — explicit start still needed."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Unmask a unit","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["unmask","{{ args.unit }}"]}},{"id":"systemd.vacuum_journal","title":"Vacuum the systemd journal","summary":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","description":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","kind":"exec","risk":"high","side_effects":["Deletes journal records older than the cutoff.","Frees disk under /var/log/journal."],"args":[{"name":"cutoff","type":"string","required":true,"description":"Vacuum window (e.g. \"7d\", \"30d\", \"12h\").","validation":{"pattern":"^[0-9]{1,4}[smhdw]$"}}],"examples":[{"title":"Keep last 7 days","args":{"cutoff":"7d"}}],"search_terms":["shrink journal","reclaim disk space"],"command":{"binary":"journalctl","argv":["--vacuum-time={{ args.cutoff }}"]}},{"id":"systemd.watchdog_status","title":"Watchdog status across units","summary":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","description":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","kind":"exec","risk":"low","side_effects":["Iterates systemctl show across all units.","Read-only."],"args":[],"examples":[{"title":"Units with watchdog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl list-units --type=service --plain --no-legend --no-pager | awk '{print $1}' | while read u; do v=$(systemctl show \"$u\" -p WatchdogUSec --value 2>/dev/null); if [ -n \"$v\" ] && [ \"$v\" != \"0\" ]; then echo \"$u: $v\"; fi; done"]}}]},{"version":"0.1.14","content_hash":"sha256:6a33200ab8a237e2f0b5811d875d90b669abb302146ef7a5b0fc2221a12967a9","tarball_url":"https://registry.emisar.dev/v1/packs/systemd-deep/0.1.14/6a33200ab8a237e2f0b5811d875d90b669abb302146ef7a5b0fc2221a12967a9/pack.tar.gz","actions":[{"id":"systemd.analyze_blame","title":"systemd-analyze blame","summary":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","description":"Show the top 30 units sorted by how long they took to start. Use to find a slow boot.","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[],"examples":[{"title":"Slowest 30 units","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemd-analyze blame | head -30"]}},{"id":"systemd.analyze_critical_chain","title":"systemd-analyze critical-chain","summary":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","description":"Show the boot-time critical path leading to one unit — useful for understanding \"why did multi-user.target take so long?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to analyze.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Boot path for multi-user","args":{"unit":"multi-user.target"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemd-analyze critical-chain \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.analyze_security","title":"systemd-analyze security","summary":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","description":"Score one unit by its sandboxing posture — NoNewPrivileges, ProtectSystem, CapabilityBoundingSet, etc. Use to audit \"how locked down is this service?\"","kind":"exec","risk":"low","side_effects":["One systemd-analyze invocation.","Read-only."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit to audit.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Audit nginx sandboxing","args":{"unit":"nginx.service"}}],"search_terms":["hardening","exposure"],"command":{"binary":"systemd-analyze","argv":["security","{{ args.unit }}"]}},{"id":"systemd.boot_errors","title":"Boot-time journal errors","summary":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","description":"`journalctl -b -p err` — every error-priority log line from the current boot. Use to triage a \"is everything healthy?\" check.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Boot errors","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","journalctl -b -p err --no-pager | tail -100"]}},{"id":"systemd.cgroup_top","title":"systemd-cgtop (3 samples)","summary":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","description":"Show three batched cgtop samples — CPU + memory + IO + tasks per cgroup. The systemd-aware top equivalent.","kind":"exec","risk":"low","side_effects":["One systemd-cgtop invocation lasting ~3s.","Read-only."],"args":[],"examples":[{"title":"cgtop snapshot","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgtop","argv":["-b","-n","3"]}},{"id":"systemd.cgroup_tree","title":"systemd cgroup tree","summary":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","description":"`systemd-cgls` — the full cgroup hierarchy with process names. Use to understand resource accounting.","kind":"exec","risk":"low","side_effects":["One systemd-cgls invocation.","Read-only."],"args":[],"examples":[{"title":"cgroup hierarchy","args":{}}],"search_terms":[],"command":{"binary":"systemd-cgls","argv":["--no-pager"]}},{"id":"systemd.daemon_reload","title":"systemctl daemon-reload","summary":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","description":"Re-read unit files from disk. Required after editing a unit file or installing a new package. Without this, systemctl restart still uses the old unit definition.","kind":"exec","risk":"medium","side_effects":["systemd re-reads all unit files.","Running units unaffected; their definitions update on next restart."],"args":[],"examples":[{"title":"Pick up unit file changes","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["daemon-reload"]}},{"id":"systemd.failed_units","title":"Failed systemd units","summary":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","description":"`systemctl --failed` — every unit not in `active` state with its last failure reason. The fast \"what is broken on this host?\" check.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"Anything failed?","args":{}}],"search_terms":["service failing","keeps crashing","crashed"],"command":{"binary":"systemctl","argv":["--failed","--no-pager","--no-legend"]}},{"id":"systemd.journal_disk_usage","title":"journalctl --disk-usage","summary":"Show how much disk the systemd journal is using.","description":"Show how much disk the systemd journal is using.","kind":"exec","risk":"low","side_effects":["One journalctl invocation.","Read-only."],"args":[],"examples":[{"title":"Journal disk usage","args":{}}],"search_terms":["journal size"],"command":{"binary":"journalctl","argv":["--disk-usage"]}},{"id":"systemd.list_unit_files","title":"List installed unit files","summary":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","description":"`systemctl list-unit-files --type=service` — every service file on disk with its enabled/disabled state.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All unit files + enable state","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-unit-files","--type=service","--no-pager","--no-legend"]}},{"id":"systemd.list_units","title":"List all systemd units","summary":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","description":"`systemctl list-units --type=service --all` — every service known to systemd, active or inactive.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All services","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-units","--type=service","--all","--no-pager","--no-legend"]}},{"id":"systemd.reset_failed","title":"systemctl reset-failed [unit]","summary":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","description":"Clear the \"failed\" state from units that crashed. Required before start-limit thresholds reset and the unit can be auto-restarted. Without a unit name, resets every failed unit.","kind":"exec","risk":"medium","side_effects":["Failed-state flag cleared.","Start-limit counter reset.","Unit not started — explicit start still needed if desired."],"args":[{"name":"unit","type":"string","required":false,"default":"","description":"Unit name (empty for all failed units).","validation":{"pattern":"^([a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127})?$"}}],"examples":[{"title":"Reset all failed","args":{}},{"title":"Reset one unit","args":{"unit":"myapp.service"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl reset-failed \"$1\"","emisar","{{ args.unit }}"]}},{"id":"systemd.sockets","title":"systemd-managed sockets","summary":"`systemctl list-sockets` — every socket-activated unit with its listening address.","description":"`systemctl list-sockets` — every socket-activated unit with its listening address.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All sockets","args":{}}],"search_terms":[],"command":{"binary":"systemctl","argv":["list-sockets","--no-pager","--no-legend"]}},{"id":"systemd.timers","title":"Active systemd timers","summary":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","description":"`systemctl list-timers` — every timer with its next-elapse and last-trigger. The systemd replacement for crontab.","kind":"exec","risk":"low","side_effects":["One systemctl invocation.","Read-only."],"args":[],"examples":[{"title":"All timers","args":{}}],"search_terms":["scheduled jobs"],"command":{"binary":"systemctl","argv":["list-timers","--all","--no-pager","--no-legend"]}},{"id":"systemd.unit_kill","title":"systemctl kill -s <signal> <unit>","summary":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","description":"Send a signal to a unit's main process (or all processes). Useful when a service is wedged and SIGTERM-via-stop isn't working. SIGKILL is unrecoverable mid-syscall; consider SIGTERM/SIGHUP first.","kind":"exec","risk":"high","side_effects":["Signal sent to the unit.","Behavior depends on signal — SIGHUP often triggers config reload."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}},{"name":"signal","type":"string","required":false,"default":"SIGTERM","description":"Signal name.","validation":{"enum":["SIGTERM","SIGKILL","SIGHUP","SIGUSR1","SIGUSR2","SIGINT","SIGQUIT"]}}],"examples":[{"title":"Send SIGHUP for config reload","args":{"signal":"SIGHUP","unit":"rsyslog.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["kill","-s","{{ args.signal }}","{{ args.unit }}"]}},{"id":"systemd.unit_mask","title":"systemctl mask <unit>","summary":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","description":"Prevent a unit from being started, even by dependencies. Symlinks the unit to /dev/null. Used to disable a unit that another package keeps re-enabling. Reversible with unmask.","kind":"exec","risk":"high","side_effects":["Unit cannot be started until unmasked.","Dependency chains referencing this unit may fail to activate."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Mask a noisy service","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["mask","{{ args.unit }}"]}},{"id":"systemd.unit_reload","title":"systemctl reload <unit>","summary":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","description":"Ask one unit to reload its config without restarting. Only works if the unit has ExecReload= defined. Use over `restart` whenever possible — no downtime.","kind":"exec","risk":"high","side_effects":["Unit re-reads its config.","Process keeps running; PID unchanged.","In-flight requests survive."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Reload nginx without restart","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["reload","{{ args.unit }}"]}},{"id":"systemd.unit_restart","title":"systemctl restart <unit>","summary":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","description":"Stop then start one unit. The service is unavailable during the gap (typically <1s for healthy services, much longer if it has a long shutdown). Workload-bearing units mean a real outage — prefer reload when supported.","kind":"exec","risk":"high","side_effects":["Service stopped then started.","In-flight requests/connections terminated mid-restart.","PID changes; any reverse-proxy or supervisor must re-resolve."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name (e.g., nginx.service).","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Restart nginx","args":{"unit":"nginx.service"}}],"search_terms":["bounce service"],"command":{"binary":"systemctl","argv":["restart","{{ args.unit }}"]}},{"id":"systemd.unit_show","title":"systemctl show <unit>","summary":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","description":"Show the full property dump for one unit — every directive (CPUShares, MemoryMax, Restart, ExecStart, etc). This surfaces the unit's `Environment=` values and full ExecStart command line, which commonly carry injected secrets (DB URLs, API keys, tokens). The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"high","side_effects":["One systemctl invocation.","Read-only, but exposes the unit's Environment= values and ExecStart (may include secrets)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@:_.][a-zA-Z0-9@:_.\\-]{0,127}$"}}],"examples":[{"title":"Full nginx properties","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["show","{{ args.unit }}","--no-pager"]}},{"id":"systemd.unit_start","title":"systemctl start <unit>","summary":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","description":"Start one unit. If already running, no-op. Use after a stop or reset_failed to bring a service back.","kind":"exec","risk":"high","side_effects":["Service started, along with any units it requires.","Triggers the unit's ExecStartPre/ExecStartPost hooks."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Start a unit","args":{"unit":"nginx.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["start","{{ args.unit }}"]}},{"id":"systemd.unit_stop","title":"systemctl stop <unit>","summary":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","description":"Stop one unit. Workload-bearing units stay down until manually started or auto-restarted by `Restart=`. Use during incident containment or planned downtime.","kind":"exec","risk":"high","side_effects":["Service stopped.","In-flight work terminated.","Stays stopped until started again (or Restart= triggers)."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Stop a misbehaving worker","args":{"unit":"stuck-worker.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["stop","{{ args.unit }}"]}},{"id":"systemd.unit_unmask","title":"systemctl unmask <unit>","summary":"Undo `mask` for one unit. The unit can be started again.","description":"Undo `mask` for one unit. The unit can be started again.","kind":"exec","risk":"medium","side_effects":["Unit no longer masked.","Unit not started — explicit start still needed."],"args":[{"name":"unit","type":"string","required":true,"description":"Unit name.","validation":{"pattern":"^[a-zA-Z0-9@_][a-zA-Z0-9@_\\-.]{0,127}$"}}],"examples":[{"title":"Unmask a unit","args":{"unit":"snapd.service"}}],"search_terms":[],"command":{"binary":"systemctl","argv":["unmask","{{ args.unit }}"]}},{"id":"systemd.vacuum_journal","title":"Vacuum the systemd journal","summary":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","description":"Drop journal records older than the cutoff time. Frees disk but loses forensic history. Provide cutoff as a journalctl --vacuum-time value (e.g. \"7d\", \"30d\").","kind":"exec","risk":"high","side_effects":["Deletes journal records older than the cutoff.","Frees disk under /var/log/journal."],"args":[{"name":"cutoff","type":"string","required":true,"description":"Vacuum window (e.g. \"7d\", \"30d\", \"12h\").","validation":{"pattern":"^[0-9]{1,4}[smhdw]$"}}],"examples":[{"title":"Keep last 7 days","args":{"cutoff":"7d"}}],"search_terms":["shrink journal","reclaim disk space"],"command":{"binary":"journalctl","argv":["--vacuum-time={{ args.cutoff }}"]}},{"id":"systemd.watchdog_status","title":"Watchdog status across units","summary":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","description":"List every unit with a non-zero WatchdogUSec property — services that have systemd-level watchdog supervision.","kind":"exec","risk":"low","side_effects":["Iterates systemctl show across all units.","Read-only."],"args":[],"examples":[{"title":"Units with watchdog","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","systemctl list-units --type=service --plain --no-legend --no-pager | awk '{print $1}' | while read u; do v=$(systemctl show \"$u\" -p WatchdogUSec --value 2>/dev/null); if [ -n \"$v\" ] && [ \"$v\" != \"0\" ]; then echo \"$u: $v\"; fi; done"]}}]}],"retired_below":"0.1.14"},{"id":"tailscale","name":"Tailscale","version":"0.1.7","description":"Inspect the host's Tailscale node via the tailscale CLI: tailnet status and peer/online map, network connectivity (netcheck DERP latency, port-mapping), ping to peers, whois lookups, this node's tailnet IPs, version, available exit nodes, MagicDNS/DNS config, and the current prefs (advertised routes, configured exit node). Read-only.","vendor":"emisar","homepage":"https://emisar.dev/packs/tailscale","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/tailscale","content_hash":"sha256:cb47c56c8688e7416d7fbe020697a5df1e41489874f2eb03105eb9377a6e01ef","tarball_url":"https://registry.emisar.dev/v1/packs/tailscale/0.1.7/cb47c56c8688e7416d7fbe020697a5df1e41489874f2eb03105eb9377a6e01ef/pack.tar.gz","requires":{"os":["linux"],"binaries":["tailscale"]},"detect":{"binaries":["tailscale"],"processes":["tailscaled"],"ports":[]},"setup":{"summary":"Reads the local host's Tailscale state via the tailscale CLI — no credentials needed. On standard Linux installs, tailscaled authorizes these read-only LocalAPI calls for ordinary local users.","notes":["Every action in this pack is read-only — it only reads tailnet/node state and never changes configuration, routes, or the exit node.","On standard Linux tailscaled accepts read-only CLI requests from ordinary local users; do not set `--operator` for this pack because that grants configuration authority these actions do not need.","TLS cert expiry is intentionally NOT in this pack: `tailscale cert` issues/renews a certificate (a mutator), so it would not be read-only. To check a cert's expiry read-only, use emisar's `ssl-local` or `network-tls` pack instead."],"verify":"tailscale.version"},"actions":[{"id":"tailscale.debug_prefs","title":"tailscale debug prefs","summary":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","description":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — prints prefs, changes nothing."],"args":[],"examples":[{"title":"Current prefs (advertised routes, configured exit node)","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["debug","prefs"]}},{"id":"tailscale.dns_status","title":"tailscale dns status","summary":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","description":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"MagicDNS / DNS configuration","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["dns","status"]}},{"id":"tailscale.exit_node_list","title":"tailscale exit-node list","summary":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","description":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"List available exit nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(tailscale exit-node list 2>&1); rc=$?\nprintf '%s\\n' \"$out\"\nif [ \"$rc\" -eq 0 ] || printf '%s' \"$out\" | grep -q 'no exit nodes found'; then exit 0; fi\nexit \"$rc\"\n"]}},{"id":"tailscale.ip","title":"tailscale ip","summary":"Show this node's tailnet IPs (IPv4 and IPv6).","description":"Show this node's tailnet IPs (IPv4 and IPv6).","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"This node's tailnet IPs","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["ip"]}},{"id":"tailscale.netcheck","title":"tailscale netcheck --format=json","summary":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","description":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — probes connectivity, changes nothing."],"args":[],"examples":[{"title":"Connectivity report","args":{}}],"search_terms":["vpn flaky","mesh connectivity","nat traversal"],"command":{"binary":"tailscale","argv":["netcheck","--format=json"]}},{"id":"tailscale.ping","title":"tailscale ping <host>","summary":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","description":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","kind":"exec","risk":"low","side_effects":["Sends Tailscale ping probes to one peer.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Peer to ping — a tailnet hostname, MagicDNS name, or Tailscale IP.","validation":{"pattern":"^[A-Za-z0-9._:][A-Za-z0-9._:-]{0,127}$"}},{"name":"count","type":"integer","required":false,"default":5,"description":"Number of pings to send (1-20).","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping a peer by MagicDNS name","args":{"host":"db-1"}},{"title":"Ping a peer ten times","args":{"count":10,"host":"100.101.102.103"}}],"search_terms":["peer unreachable"],"command":{"binary":"tailscale","argv":["ping","--c","{{ args.count }}","{{ args.host }}"]}},{"id":"tailscale.status","title":"tailscale status --json","summary":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","description":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Full tailnet status","args":{}}],"search_terms":["vpn","mesh network","offline peers"],"command":{"binary":"tailscale","argv":["status","--json"]}},{"id":"tailscale.version","title":"tailscale version --json","summary":"Show Tailscale client version and build info as JSON.","description":"Show Tailscale client version and build info as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Client version and build info","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["version","--json"]}},{"id":"tailscale.whois","title":"tailscale whois --json <ip>","summary":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","description":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"Tailscale IP (IPv4 or IPv6) to look up.","validation":{"pattern":"^[0-9a-fA-F:.]{2,64}$"}}],"examples":[{"title":"Who owns this tailnet IP","args":{"ip":"100.101.102.103"}}],"search_terms":[],"command":{"binary":"tailscale","argv":["whois","--json","{{ args.ip }}"]}}],"previous_versions":[{"version":"0.1.6","content_hash":"sha256:ab087ffb5dccdb36d5ab00252445cd1e6388708ac0501674270adee3ddf4afc3","tarball_url":"https://registry.emisar.dev/v1/packs/tailscale/0.1.6/ab087ffb5dccdb36d5ab00252445cd1e6388708ac0501674270adee3ddf4afc3/pack.tar.gz","actions":[{"id":"tailscale.debug_prefs","title":"tailscale debug prefs","summary":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","description":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — prints prefs, changes nothing."],"args":[],"examples":[{"title":"Current prefs (advertised routes, configured exit node)","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["debug","prefs"]}},{"id":"tailscale.dns_status","title":"tailscale dns status","summary":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","description":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"MagicDNS / DNS configuration","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["dns","status"]}},{"id":"tailscale.exit_node_list","title":"tailscale exit-node list","summary":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","description":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"List available exit nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(tailscale exit-node list 2>&1); rc=$?\nprintf '%s\\n' \"$out\"\nif [ \"$rc\" -eq 0 ] || printf '%s' \"$out\" | grep -q 'no exit nodes found'; then exit 0; fi\nexit \"$rc\"\n"]}},{"id":"tailscale.ip","title":"tailscale ip","summary":"Show this node's tailnet IPs (IPv4 and IPv6).","description":"Show this node's tailnet IPs (IPv4 and IPv6).","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"This node's tailnet IPs","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["ip"]}},{"id":"tailscale.netcheck","title":"tailscale netcheck --format=json","summary":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","description":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — probes connectivity, changes nothing."],"args":[],"examples":[{"title":"Connectivity report","args":{}}],"search_terms":["vpn flaky","mesh connectivity","nat traversal"],"command":{"binary":"tailscale","argv":["netcheck","--format=json"]}},{"id":"tailscale.ping","title":"tailscale ping <host>","summary":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","description":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","kind":"exec","risk":"low","side_effects":["Sends Tailscale ping probes to one peer.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Peer to ping — a tailnet hostname, MagicDNS name, or Tailscale IP.","validation":{"pattern":"^[A-Za-z0-9._:][A-Za-z0-9._:-]{0,127}$"}},{"name":"count","type":"integer","required":false,"default":5,"description":"Number of pings to send (1-20).","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping a peer by MagicDNS name","args":{"host":"db-1"}},{"title":"Ping a peer ten times","args":{"count":10,"host":"100.101.102.103"}}],"search_terms":["peer unreachable"],"command":{"binary":"tailscale","argv":["ping","--c","{{ args.count }}","{{ args.host }}"]}},{"id":"tailscale.status","title":"tailscale status --json","summary":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","description":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Full tailnet status","args":{}}],"search_terms":["vpn","mesh network","offline peers"],"command":{"binary":"tailscale","argv":["status","--json"]}},{"id":"tailscale.version","title":"tailscale version --json","summary":"Show Tailscale client version and build info as JSON.","description":"Show Tailscale client version and build info as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Client version and build info","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["version","--json"]}},{"id":"tailscale.whois","title":"tailscale whois --json <ip>","summary":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","description":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"Tailscale IP (IPv4 or IPv6) to look up.","validation":{"pattern":"^[0-9a-fA-F:.]{2,64}$"}}],"examples":[{"title":"Who owns this tailnet IP","args":{"ip":"100.101.102.103"}}],"search_terms":[],"command":{"binary":"tailscale","argv":["whois","--json","{{ args.ip }}"]}}]},{"version":"0.1.5","content_hash":"sha256:9006cd26440824d11235e5861631a99690f72b46b9cfb37807bb4670ec831b51","tarball_url":"https://registry.emisar.dev/v1/packs/tailscale/0.1.5/9006cd26440824d11235e5861631a99690f72b46b9cfb37807bb4670ec831b51/pack.tar.gz","actions":[{"id":"tailscale.debug_prefs","title":"tailscale debug prefs","summary":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","description":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — prints prefs, changes nothing."],"args":[],"examples":[{"title":"Current prefs (advertised routes, configured exit node)","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["debug","prefs"]}},{"id":"tailscale.dns_status","title":"tailscale dns status","summary":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","description":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"MagicDNS / DNS configuration","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["dns","status"]}},{"id":"tailscale.exit_node_list","title":"tailscale exit-node list","summary":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","description":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"List available exit nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(tailscale exit-node list 2>&1); rc=$?\nprintf '%s\\n' \"$out\"\nif [ \"$rc\" -eq 0 ] || printf '%s' \"$out\" | grep -q 'no exit nodes found'; then exit 0; fi\nexit \"$rc\"\n"]}},{"id":"tailscale.ip","title":"tailscale ip","summary":"Show this node's tailnet IPs (IPv4 and IPv6).","description":"Show this node's tailnet IPs (IPv4 and IPv6).","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"This node's tailnet IPs","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["ip"]}},{"id":"tailscale.netcheck","title":"tailscale netcheck --format=json","summary":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","description":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — probes connectivity, changes nothing."],"args":[],"examples":[{"title":"Connectivity report","args":{}}],"search_terms":["vpn flaky","mesh connectivity","nat traversal"],"command":{"binary":"tailscale","argv":["netcheck","--format=json"]}},{"id":"tailscale.ping","title":"tailscale ping <host>","summary":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","description":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","kind":"exec","risk":"low","side_effects":["Sends Tailscale ping probes to one peer.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Peer to ping — a tailnet hostname, MagicDNS name, or Tailscale IP.","validation":{"pattern":"^[A-Za-z0-9._:][A-Za-z0-9._:-]{0,127}$"}},{"name":"count","type":"integer","required":false,"default":5,"description":"Number of pings to send (1-20).","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping a peer by MagicDNS name","args":{"host":"db-1"}},{"title":"Ping a peer ten times","args":{"count":10,"host":"100.101.102.103"}}],"search_terms":["peer unreachable"],"command":{"binary":"tailscale","argv":["ping","--c","{{ args.count }}","{{ args.host }}"]}},{"id":"tailscale.status","title":"tailscale status --json","summary":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","description":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Full tailnet status","args":{}}],"search_terms":["vpn","mesh network","offline peers"],"command":{"binary":"tailscale","argv":["status","--json"]}},{"id":"tailscale.version","title":"tailscale version --json","summary":"Show Tailscale client version and build info as JSON.","description":"Show Tailscale client version and build info as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Client version and build info","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["version","--json"]}},{"id":"tailscale.whois","title":"tailscale whois --json <ip>","summary":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","description":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"Tailscale IP (IPv4 or IPv6) to look up.","validation":{"pattern":"^[0-9a-fA-F:.]{2,64}$"}}],"examples":[{"title":"Who owns this tailnet IP","args":{"ip":"100.101.102.103"}}],"search_terms":[],"command":{"binary":"tailscale","argv":["whois","--json","{{ args.ip }}"]}}]},{"version":"0.1.4","content_hash":"sha256:fc2a4b5d7f8bf5eb71af8fa8505a72f747d8f333b1bc782e9466ebebfbbe7cea","tarball_url":"https://registry.emisar.dev/v1/packs/tailscale/0.1.4/fc2a4b5d7f8bf5eb71af8fa8505a72f747d8f333b1bc782e9466ebebfbbe7cea/pack.tar.gz","actions":[{"id":"tailscale.debug_prefs","title":"tailscale debug prefs","summary":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","description":"Show current node prefs as JSON, including AdvertiseRoutes (this node's advertised subnet routes) and ExitNodeIP/ExitNodeID (the configured exit node, if any). Read-only print of the in-memory prefs.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — prints prefs, changes nothing."],"args":[],"examples":[{"title":"Current prefs (advertised routes, configured exit node)","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["debug","prefs"]}},{"id":"tailscale.dns_status","title":"tailscale dns status","summary":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","description":"Show MagicDNS and DNS configuration for this node — nameservers, search domains, split-DNS routes, and whether MagicDNS is enabled.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"MagicDNS / DNS configuration","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["dns","status"]}},{"id":"tailscale.exit_node_list","title":"tailscale exit-node list","summary":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","description":"List available exit nodes on the tailnet (hostname, country, city, status). Succeeds with no rows when the tailnet has no exit nodes (a benign empty state); a real failure (tailscaled down / not logged in) still reports failed.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"List available exit nodes","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","out=$(tailscale exit-node list 2>&1); rc=$?\nprintf '%s\\n' \"$out\"\nif [ \"$rc\" -eq 0 ] || printf '%s' \"$out\" | grep -q 'no exit nodes found'; then exit 0; fi\nexit \"$rc\"\n"]}},{"id":"tailscale.ip","title":"tailscale ip","summary":"Show this node's tailnet IPs (IPv4 and IPv6).","description":"Show this node's tailnet IPs (IPv4 and IPv6).","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"This node's tailnet IPs","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["ip"]}},{"id":"tailscale.netcheck","title":"tailscale netcheck --format=json","summary":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","description":"Show network connectivity report as JSON — DERP latency, UDP reachability, IPv4/IPv6 support, port-mapping (UPnP/PMP/PCP), and PreferredDERP.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only — probes connectivity, changes nothing."],"args":[],"examples":[{"title":"Connectivity report","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["netcheck","--format=json"]}},{"id":"tailscale.ping","title":"tailscale ping <host>","summary":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","description":"Ping a tailnet peer over Tailscale and report the path (direct vs DERP) and latency. Terminates on its own — the bounded count (default 5, max 20) means it stops after that many replies or attempts.","kind":"exec","risk":"low","side_effects":["Sends Tailscale ping probes to one peer.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"Peer to ping — a tailnet hostname, MagicDNS name, or Tailscale IP.","validation":{"pattern":"^[A-Za-z0-9._:][A-Za-z0-9._:-]{0,127}$"}},{"name":"count","type":"integer","required":false,"default":5,"description":"Number of pings to send (1-20).","validation":{"min":1,"max":20}}],"examples":[{"title":"Ping a peer by MagicDNS name","args":{"host":"db-1"}},{"title":"Ping a peer ten times","args":{"count":10,"host":"100.101.102.103"}}],"search_terms":[],"command":{"binary":"tailscale","argv":["ping","--c","{{ args.count }}","{{ args.host }}"]}},{"id":"tailscale.status","title":"tailscale status --json","summary":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","description":"Show tailnet status as JSON — the peer/online map: Self, Peer{}, Online, ExitNodeStatus, TailscaleIPs, and Health.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Full tailnet status","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["status","--json"]}},{"id":"tailscale.version","title":"tailscale version --json","summary":"Show Tailscale client version and build info as JSON.","description":"Show Tailscale client version and build info as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[],"examples":[{"title":"Client version and build info","args":{}}],"search_terms":[],"command":{"binary":"tailscale","argv":["version","--json"]}},{"id":"tailscale.whois","title":"tailscale whois --json <ip>","summary":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","description":"Identify which tailnet node and user own a Tailscale IP — returns the node, user, and capabilities as JSON.","kind":"exec","risk":"low","side_effects":["One tailscale read.","Read-only."],"args":[{"name":"ip","type":"string","required":true,"description":"Tailscale IP (IPv4 or IPv6) to look up.","validation":{"pattern":"^[0-9a-fA-F:.]{2,64}$"}}],"examples":[{"title":"Who owns this tailnet IP","args":{"ip":"100.101.102.103"}}],"search_terms":[],"command":{"binary":"tailscale","argv":["whois","--json","{{ args.ip }}"]}}]}],"retired_below":"0.1.4"},{"id":"terraform-readonly","name":"Terraform / OpenTofu read-only ops","version":"0.7.8","description":"Read-only Terraform or OpenTofu CLI actions for inspecting a workspace. NO apply, NO destroy, NO state mutation — those should happen in CI, not via a runner. Operates in the directory given by TF_DIR env var, running whichever CLI TF_BIN names — `terraform` by default, `tofu` on an OpenTofu host, so one of those two must be on PATH.","vendor":"emisar","homepage":"https://emisar.dev/packs/terraform-readonly","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/terraform-readonly","content_hash":"sha256:8742655241d79d7c1f5e4c0086d9534ba2e3c5833373dedcf12e45af1668c79a","tarball_url":"https://registry.emisar.dev/v1/packs/terraform-readonly/0.7.8/8742655241d79d7c1f5e4c0086d9534ba2e3c5833373dedcf12e45af1668c79a/pack.tar.gz","requires":{"os":["linux"],"binaries":["jq","bash"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Every action runs `cd \"$TF_DIR\" && terraform …`, so `TF_DIR` must point at an initialized working directory on the runner host. Set `TF_BIN`=tofu to drive OpenTofu instead. Provider and backend credentials come from that config, not from this pack.","env":[{"name":"TF_DIR","required":true,"description":"Path to an initialized working directory (already `terraform init`-ed, with .terraform and a backend configured).","example":"/srv/infra/prod"},{"name":"TF_BIN","description":"CLI that runs every action. Set it to `tofu` on an OpenTofu host; the two are command-compatible for everything this pack calls.","default":"terraform","example":"tofu"},{"name":"TF_STATE_CANDIDATE_DIR","description":"Optional restricted directory containing candidate .tfstate files for metadata inspection and comparison.","example":"/srv/infra/recovery"},{"name":"TF_PLAN_DIR","description":"Optional restricted directory where CI drops saved plan files for plan_file_summary to review.","example":"/srv/infra/plans"}],"notes":["Provider and backend auth depend entirely on what the config uses: an AWS provider/backend reads AWS_* (or an EC2/role profile), GCP reads GOOGLE_APPLICATION_CREDENTIALS, and so on — allowlist whatever your config needs.","state_list, state_show, show_json, output, state_metadata, and state_compare_metadata read the backend state, so the backend credentials must be reachable; validate, version, state_file_metadata, and plan_file_summary do not.","plan_no_save and plan_summary (both risk medium) call every provider's read APIs (quota usage) and briefly hold the state lock, but never write state or save an applyable plan.","For review, prefer plan_summary over plan_no_save and show_json: it returns addresses, actions, counts, drift, and diagnostics as JSON while emitting no attribute or output values. plan_file_summary returns the same shape for a plan CI already saved, without contacting a provider.","plan_summary needs a workspace that plans ON THIS HOST. What decides that is the HCP Terraform / Terraform Enterprise workspace's execution mode, not the backend: a `cloud` block with execution mode `local` works fine, while `remote` and `agent` stream the run's human output instead of machine-readable messages. The action fails closed there rather than reporting an empty plan; use the hcp-terraform pack for those workspaces. plan_no_save still works everywhere, and the state-reading actions are unaffected.","`state pull` may upgrade state to the local CLI's readable format; terraform_version in projected metadata can therefore reflect the runner's CLI rather than the writer of the remote snapshot.","`TF_BIN` only reaches the action when the runner's `inherit_env` allowlists it, exactly like `TF_DIR` — an unset `TF_BIN` runs `terraform`."],"host_access":[{"actions":["tf.version","tf.providers","tf.state_list","tf.state_show","tf.show_json","tf.output","tf.validate","tf.plan_file_summary","tf.state_metadata","tf.state_file_metadata","tf.state_compare_metadata","tf.plan_no_save","tf.plan_summary"],"requirement":"Read the Terraform workspace and create its local lock or working files while planning.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-terraform-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root","sudo test -r /srv/infra/prod","sudo test -w /srv/infra/prod"],"impact":"Every Emisar action on this runner executes as root and can read or modify local Terraform files, including state and embedded secrets. Pack policy still limits commands."}]}],"verify":"tf.version"},"actions":[{"id":"tf.output","title":"terraform output -json","summary":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","description":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but un-masks `sensitive` outputs (may include secrets)."],"args":[],"examples":[{"title":"Outputs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" output -json"]}},{"id":"tf.plan_file_summary","title":"Project a saved plan into a reviewable summary","summary":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed.","description":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. The filename must resolve beneath TF_PLAN_DIR; symlink and traversal escapes fail closed. A saved plan stores every attribute and output value in cleartext, sensitive ones included; this projection reads none of them.","kind":"script","risk":"low","side_effects":["Reads one saved plan file capped at 32 MiB, plus the workspace's provider schemas.","Contacts no provider and never modifies the plan or state."],"args":[{"name":"plan_file","type":"string","required":true,"description":"Saved plan basename under TF_PLAN_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}$","max_length":127}}],"examples":[{"title":"Review the plan CI just built","args":{"plan_file":"review.tfplan"}}],"search_terms":["review saved plan","review CI plan","what will this apply change"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan_file"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.plan_no_save","title":"terraform plan","summary":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","description":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","kind":"exec","risk":"medium","side_effects":["Calls every provider's read API — quota usage applies.","Read-only — does not modify state or save a plan file."],"args":[],"examples":[{"title":"Plan","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" plan -input=false -no-color"]}},{"id":"tf.plan_summary","title":"Project a fresh plan into a reviewable summary","summary":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics.","description":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics. The summary counts always cover the whole plan; the change, drift, output, and diagnostic lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, and names — so a plan can be reviewed without dumping the secrets a full plan carries in cleartext. Saves no plan file, so nothing this returns can be applied. Needs a workspace that plans on this host: HCP Terraform and Terraform Enterprise workspaces set to remote or agent execution stream no structured output, and this fails rather than reporting an empty plan — review those with the hcp-terraform pack. A `cloud` block alone is fine; what decides it is the workspace's execution mode.","kind":"script","risk":"medium","side_effects":["Calls every provider's read API to refresh state — quota usage applies.","Briefly holds the backend's state lock while planning.","Read-only — writes no state and saves no applyable plan."],"args":[],"examples":[{"title":"Review what a plan would change","args":{}}],"search_terms":["review plan","what will change","blast radius","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.providers","title":"terraform providers","summary":"List all providers declared in the workspace + their constraints.","description":"List all providers declared in the workspace + their constraints.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Providers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" providers"]}},{"id":"tf.show_json","title":"terraform show -json","summary":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","description":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but dumps every resource attribute (may include secrets)."],"args":[],"examples":[{"title":"State JSON","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" show -json"]}},{"id":"tf.state_compare_metadata","title":"Compare live and candidate Terraform state metadata","summary":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","description":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","kind":"script","risk":"low","side_effects":["One read-only backend state pull and one candidate file read.","Never emits state values or modifies either state."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Compare a failed-upload candidate","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$defs":{"metadata":{"additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"enum":["live","candidate"]},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"candidate":{"$ref":"#/$defs/metadata"},"live":{"$ref":"#/$defs/metadata"},"relation":{"enum":["lineage_mismatch","candidate_older","candidate_newer","equal_serial"]},"serial_delta":{"type":["integer","null"]}},"required":["live","candidate","relation","serial_delta"],"type":"object"}},{"id":"tf.state_file_metadata","title":"Project candidate Terraform state metadata","summary":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","description":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","kind":"script","risk":"low","side_effects":["Reads one candidate state file capped at 64 MiB.","Never emits state values or modifies the file."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Candidate metadata","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"candidate"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_list","title":"terraform state list","summary":"List all resource addresses currently in state.","description":"List all resource addresses currently in state.","kind":"exec","risk":"low","side_effects":["Reads state file.","Read-only."],"args":[],"examples":[{"title":"State resources","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state list"]}},{"id":"tf.state_metadata","title":"Project live Terraform state metadata","summary":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","description":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","kind":"script","risk":"low","side_effects":["One read-only backend state pull.","Holds at most 64 MiB of raw state in process memory before projecting metadata."],"args":[],"examples":[{"title":"Current backend metadata","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"live"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_show","title":"terraform state show <address>","summary":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","description":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only — output may contain sensitive attributes; rely on redaction."],"args":[{"name":"address","type":"string","required":true,"description":"Resource address (e.g. 'aws_instance.api').","validation":{"pattern":"^[a-zA-Z0-9_.\\-\\[\\]\"]{1,256}$"}}],"examples":[{"title":"One resource","args":{"address":"aws_instance.api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state show ''\"$1\"''","emisar","{{ args.address }}"]}},{"id":"tf.validate","title":"terraform validate","summary":"Validate the workspace's HCL files. No state read or write.","description":"Validate the workspace's HCL files. No state read or write.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Validate","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" validate"]}},{"id":"tf.version","title":"terraform version","summary":"Show the CLI version + provider versions.","description":"Show the CLI version + provider versions.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" version"]}}],"previous_versions":[{"version":"0.7.6","content_hash":"sha256:d74414a351e4b298c11491160f8dfb8820777d30f28fc3297d909b85288efc0e","tarball_url":"https://registry.emisar.dev/v1/packs/terraform-readonly/0.7.6/d74414a351e4b298c11491160f8dfb8820777d30f28fc3297d909b85288efc0e/pack.tar.gz","actions":[{"id":"tf.output","title":"terraform output -json","summary":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","description":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but un-masks `sensitive` outputs (may include secrets)."],"args":[],"examples":[{"title":"Outputs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" output -json"]}},{"id":"tf.plan_file_summary","title":"Project a saved plan into a reviewable summary","summary":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed.","description":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. The filename must resolve beneath TF_PLAN_DIR; symlink and traversal escapes fail closed. A saved plan stores every attribute and output value in cleartext, sensitive ones included; this projection reads none of them.","kind":"script","risk":"low","side_effects":["Reads one saved plan file capped at 32 MiB, plus the workspace's provider schemas.","Contacts no provider and never modifies the plan or state."],"args":[{"name":"plan_file","type":"string","required":true,"description":"Saved plan basename under TF_PLAN_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}$","max_length":127}}],"examples":[{"title":"Review the plan CI just built","args":{"plan_file":"review.tfplan"}}],"search_terms":["review saved plan","review CI plan","what will this apply change"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan_file"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.plan_no_save","title":"terraform plan","summary":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","description":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","kind":"exec","risk":"medium","side_effects":["Calls every provider's read API — quota usage applies.","Read-only — does not modify state or save a plan file."],"args":[],"examples":[{"title":"Plan","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" plan -input=false -no-color"]}},{"id":"tf.plan_summary","title":"Project a fresh plan into a reviewable summary","summary":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics.","description":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics. The summary counts always cover the whole plan; the change, drift, output, and diagnostic lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, and names — so a plan can be reviewed without dumping the secrets a full plan carries in cleartext. Saves no plan file, so nothing this returns can be applied. Needs a workspace that plans on this host: HCP Terraform and Terraform Enterprise workspaces set to remote or agent execution stream no structured output, and this fails rather than reporting an empty plan — review those with the hcp-terraform pack. A `cloud` block alone is fine; what decides it is the workspace's execution mode.","kind":"script","risk":"medium","side_effects":["Calls every provider's read API to refresh state — quota usage applies.","Briefly holds the backend's state lock while planning.","Read-only — writes no state and saves no applyable plan."],"args":[],"examples":[{"title":"Review what a plan would change","args":{}}],"search_terms":["review plan","what will change","blast radius","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.providers","title":"terraform providers","summary":"List all providers declared in the workspace + their constraints.","description":"List all providers declared in the workspace + their constraints.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Providers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" providers"]}},{"id":"tf.show_json","title":"terraform show -json","summary":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","description":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but dumps every resource attribute (may include secrets)."],"args":[],"examples":[{"title":"State JSON","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" show -json"]}},{"id":"tf.state_compare_metadata","title":"Compare live and candidate Terraform state metadata","summary":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","description":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","kind":"script","risk":"low","side_effects":["One read-only backend state pull and one candidate file read.","Never emits state values or modifies either state."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Compare a failed-upload candidate","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$defs":{"metadata":{"additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"enum":["live","candidate"]},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"candidate":{"$ref":"#/$defs/metadata"},"live":{"$ref":"#/$defs/metadata"},"relation":{"enum":["lineage_mismatch","candidate_older","candidate_newer","equal_serial"]},"serial_delta":{"type":["integer","null"]}},"required":["live","candidate","relation","serial_delta"],"type":"object"}},{"id":"tf.state_file_metadata","title":"Project candidate Terraform state metadata","summary":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","description":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","kind":"script","risk":"low","side_effects":["Reads one candidate state file capped at 64 MiB.","Never emits state values or modifies the file."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Candidate metadata","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"candidate"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_list","title":"terraform state list","summary":"List all resource addresses currently in state.","description":"List all resource addresses currently in state.","kind":"exec","risk":"low","side_effects":["Reads state file.","Read-only."],"args":[],"examples":[{"title":"State resources","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state list"]}},{"id":"tf.state_metadata","title":"Project live Terraform state metadata","summary":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","description":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","kind":"script","risk":"low","side_effects":["One read-only backend state pull.","Holds at most 64 MiB of raw state in process memory before projecting metadata."],"args":[],"examples":[{"title":"Current backend metadata","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"live"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_show","title":"terraform state show <address>","summary":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","description":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only — output may contain sensitive attributes; rely on redaction."],"args":[{"name":"address","type":"string","required":true,"description":"Resource address (e.g. 'aws_instance.api').","validation":{"pattern":"^[a-zA-Z0-9_.\\-\\[\\]\"]{1,256}$"}}],"examples":[{"title":"One resource","args":{"address":"aws_instance.api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state show ''\"$1\"''","emisar","{{ args.address }}"]}},{"id":"tf.validate","title":"terraform validate","summary":"Validate the workspace's HCL files. No state read or write.","description":"Validate the workspace's HCL files. No state read or write.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Validate","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" validate"]}},{"id":"tf.version","title":"terraform version","summary":"Show the CLI version + provider versions.","description":"Show the CLI version + provider versions.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" version"]}}]},{"version":"0.7.4","content_hash":"sha256:c2d5e1d6c8b206b48d3ace1b641275a1c903565250b79602060af7be98d5c368","tarball_url":"https://registry.emisar.dev/v1/packs/terraform-readonly/0.7.4/c2d5e1d6c8b206b48d3ace1b641275a1c903565250b79602060af7be98d5c368/pack.tar.gz","actions":[{"id":"tf.output","title":"terraform output -json","summary":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","description":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but un-masks `sensitive` outputs (may include secrets)."],"args":[],"examples":[{"title":"Outputs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" output -json"]}},{"id":"tf.plan_file_summary","title":"Project a saved plan into a reviewable summary","summary":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed.","description":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. The filename must resolve beneath TF_PLAN_DIR; symlink and traversal escapes fail closed. A saved plan stores every attribute and output value in cleartext, sensitive ones included; this projection reads none of them.","kind":"script","risk":"low","side_effects":["Reads one saved plan file capped at 32 MiB, plus the workspace's provider schemas.","Contacts no provider and never modifies the plan or state."],"args":[{"name":"plan_file","type":"string","required":true,"description":"Saved plan basename under TF_PLAN_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}$","max_length":127}}],"examples":[{"title":"Review the plan CI just built","args":{"plan_file":"review.tfplan"}}],"search_terms":["review saved plan","review CI plan","what will this apply change"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan_file"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.plan_no_save","title":"terraform plan","summary":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","description":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","kind":"exec","risk":"medium","side_effects":["Calls every provider's read API — quota usage applies.","Read-only — does not modify state or save a plan file."],"args":[],"examples":[{"title":"Plan","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" plan -input=false -no-color"]}},{"id":"tf.plan_summary","title":"Project a fresh plan into a reviewable summary","summary":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics.","description":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics. The summary counts always cover the whole plan; the change, drift, output, and diagnostic lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, and names — so a plan can be reviewed without dumping the secrets a full plan carries in cleartext. Saves no plan file, so nothing this returns can be applied. Needs a workspace that plans on this host: HCP Terraform and Terraform Enterprise workspaces set to remote or agent execution stream no structured output, and this fails rather than reporting an empty plan — review those with the hcp-terraform pack. A `cloud` block alone is fine; what decides it is the workspace's execution mode.","kind":"script","risk":"medium","side_effects":["Calls every provider's read API to refresh state — quota usage applies.","Briefly holds the backend's state lock while planning.","Read-only — writes no state and saves no applyable plan."],"args":[],"examples":[{"title":"Review what a plan would change","args":{}}],"search_terms":["review plan","what will change","blast radius","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.providers","title":"terraform providers","summary":"List all providers declared in the workspace + their constraints.","description":"List all providers declared in the workspace + their constraints.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Providers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" providers"]}},{"id":"tf.show_json","title":"terraform show -json","summary":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","description":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but dumps every resource attribute (may include secrets)."],"args":[],"examples":[{"title":"State JSON","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" show -json"]}},{"id":"tf.state_compare_metadata","title":"Compare live and candidate Terraform state metadata","summary":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","description":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","kind":"script","risk":"low","side_effects":["One read-only backend state pull and one candidate file read.","Never emits state values or modifies either state."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Compare a failed-upload candidate","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$defs":{"metadata":{"additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"enum":["live","candidate"]},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"candidate":{"$ref":"#/$defs/metadata"},"live":{"$ref":"#/$defs/metadata"},"relation":{"enum":["lineage_mismatch","candidate_older","candidate_newer","equal_serial"]},"serial_delta":{"type":["integer","null"]}},"required":["live","candidate","relation","serial_delta"],"type":"object"}},{"id":"tf.state_file_metadata","title":"Project candidate Terraform state metadata","summary":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","description":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","kind":"script","risk":"low","side_effects":["Reads one candidate state file capped at 64 MiB.","Never emits state values or modifies the file."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Candidate metadata","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"candidate"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_list","title":"terraform state list","summary":"List all resource addresses currently in state.","description":"List all resource addresses currently in state.","kind":"exec","risk":"low","side_effects":["Reads state file.","Read-only."],"args":[],"examples":[{"title":"State resources","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state list"]}},{"id":"tf.state_metadata","title":"Project live Terraform state metadata","summary":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","description":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","kind":"script","risk":"low","side_effects":["One read-only backend state pull.","Holds at most 64 MiB of raw state in process memory before projecting metadata."],"args":[],"examples":[{"title":"Current backend metadata","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"live"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_show","title":"terraform state show <address>","summary":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","description":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only — output may contain sensitive attributes; rely on redaction."],"args":[{"name":"address","type":"string","required":true,"description":"Resource address (e.g. 'aws_instance.api').","validation":{"pattern":"^[a-zA-Z0-9_.\\-\\[\\]\"]{1,256}$"}}],"examples":[{"title":"One resource","args":{"address":"aws_instance.api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state show ''\"$1\"''","emisar","{{ args.address }}"]}},{"id":"tf.validate","title":"terraform validate","summary":"Validate the workspace's HCL files. No state read or write.","description":"Validate the workspace's HCL files. No state read or write.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Validate","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" validate"]}},{"id":"tf.version","title":"terraform version","summary":"Show the CLI version + provider versions.","description":"Show the CLI version + provider versions.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" version"]}}]},{"version":"0.7.3","content_hash":"sha256:e1e17c90480793ead0b89c0ec785400256d5ddcca8d453f6d71b38d8b1dc6cf0","tarball_url":"https://registry.emisar.dev/v1/packs/terraform-readonly/0.7.3/e1e17c90480793ead0b89c0ec785400256d5ddcca8d453f6d71b38d8b1dc6cf0/pack.tar.gz","actions":[{"id":"tf.output","title":"terraform output -json","summary":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","description":"Show the workspace's output values (terraform output -json). The -json form deliberately un-masks outputs marked `sensitive`, so the values routinely carry secrets (a db_password, a kubeconfig, provider credentials) in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask output values whose arbitrary names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but un-masks `sensitive` outputs (may include secrets)."],"args":[],"examples":[{"title":"Outputs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" output -json"]}},{"id":"tf.plan_file_summary","title":"Project a saved plan into a reviewable summary","summary":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed.","description":"List what a plan file already on disk would create, update, delete, or replace, in the same shape as tf.plan_summary but without contacting any provider — this reads a plan CI has already computed. The summary counts always cover the whole plan; the change, drift, and output lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. The filename must resolve beneath TF_PLAN_DIR; symlink and traversal escapes fail closed. A saved plan stores every attribute and output value in cleartext, sensitive ones included; this projection reads none of them.","kind":"script","risk":"low","side_effects":["Reads one saved plan file capped at 32 MiB, plus the workspace's provider schemas.","Contacts no provider and never modifies the plan or state."],"args":[{"name":"plan_file","type":"string","required":true,"description":"Saved plan basename under TF_PLAN_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}$","max_length":127}}],"examples":[{"title":"Review the plan CI just built","args":{"plan_file":"review.tfplan"}}],"search_terms":["review saved plan","review CI plan","what will this apply change"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan_file"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.plan_no_save","title":"terraform plan","summary":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","description":"Compute a plan but does NOT save it (no -out). Cannot be applied from this run. May call out to providers (read API quotas).","kind":"exec","risk":"medium","side_effects":["Calls every provider's read API — quota usage applies.","Read-only — does not modify state or save a plan file."],"args":[],"examples":[{"title":"Plan","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" plan -input=false -no-color"]}},{"id":"tf.plan_summary","title":"Project a fresh plan into a reviewable summary","summary":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics.","description":"List what a fresh plan would create, update, delete, or replace, with per-action counts, resources that drifted outside Terraform, planned output changes, and diagnostics. The summary counts always cover the whole plan; the change, drift, output, and diagnostic lists keep a bounded sample — most destructive first — and `truncated` reports how many entries each list dropped, so the result fits the runner's structured-output cap on plans of any size. Attribute and output VALUES are never emitted — only addresses, types, actions, and names — so a plan can be reviewed without dumping the secrets a full plan carries in cleartext. Saves no plan file, so nothing this returns can be applied. Needs a workspace that plans on this host: HCP Terraform and Terraform Enterprise workspaces set to remote or agent execution stream no structured output, and this fails rather than reporting an empty plan — review those with the hcp-terraform pack. A `cloud` block alone is fine; what decides it is the workspace's execution mode.","kind":"script","risk":"medium","side_effects":["Calls every provider's read API to refresh state — quota usage applies.","Briefly holds the backend's state lock while planning.","Read-only — writes no state and saves no applyable plan."],"args":[],"examples":[{"title":"Review what a plan would change","args":{}}],"search_terms":["review plan","what will change","blast radius","destroy count"],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"changes":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"reason":{"maxLength":36,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action","reason"],"type":"object"},"maxItems":10,"type":"array"},"cli_version":{"maxLength":32,"type":"string"},"diagnostics":{"items":{"additionalProperties":false,"properties":{"severity":{"maxLength":12,"type":"string"},"summary":{"maxLength":100,"type":"string"}},"required":["severity","summary"],"type":"object"},"maxItems":3,"type":"array"},"drift":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"address":{"maxLength":80,"type":"string"},"module":{"maxLength":32,"type":"string"},"resource_type":{"maxLength":44,"type":"string"}},"required":["address","resource_type","module","action"],"type":"object"},"maxItems":3,"type":"array"},"outputs":{"items":{"additionalProperties":false,"properties":{"action":{"maxLength":12,"type":"string"},"name":{"maxLength":40,"type":"string"},"sensitive":{"type":"boolean"}},"required":["name","action","sensitive"],"type":"object"},"maxItems":4,"type":"array"},"source":{"const":"plan"},"summary":{"additionalProperties":false,"properties":{"create":{"minimum":0,"type":"integer"},"delete":{"minimum":0,"type":"integer"},"drifted":{"minimum":0,"type":"integer"},"import":{"minimum":0,"type":"integer"},"read":{"minimum":0,"type":"integer"},"replace":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"},"update":{"minimum":0,"type":"integer"}},"required":["total","create","update","delete","replace","read","import","drifted"],"type":"object"},"truncated":{"additionalProperties":false,"properties":{"changes":{"minimum":0,"type":"integer"},"diagnostics":{"minimum":0,"type":"integer"},"drift":{"minimum":0,"type":"integer"},"outputs":{"minimum":0,"type":"integer"}},"required":["changes","drift","outputs","diagnostics"],"type":"object"}},"required":["source","cli_version","summary","changes","drift","outputs","diagnostics","truncated"],"type":"object"}},{"id":"tf.providers","title":"terraform providers","summary":"List all providers declared in the workspace + their constraints.","description":"List all providers declared in the workspace + their constraints.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Providers","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" providers"]}},{"id":"tf.show_json","title":"terraform show -json","summary":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","description":"Show the full workspace state as JSON (terraform show -json), for programmatic queries. This dumps every resource's attributes, including ones marked `sensitive` (passwords, private keys, tokens), in cleartext; scope it by policy. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can't reliably mask secrets whose names and shapes match no rule.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only, but dumps every resource attribute (may include secrets)."],"args":[],"examples":[{"title":"State JSON","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" show -json"]}},{"id":"tf.state_compare_metadata","title":"Compare live and candidate Terraform state metadata","summary":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","description":"Compare live backend metadata with one restricted candidate state and report an explicit lineage mismatch, older or newer candidate, or equal serial. The result never recommends or performs a state mutation.","kind":"script","risk":"low","side_effects":["One read-only backend state pull and one candidate file read.","Never emits state values or modifies either state."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Compare a failed-upload candidate","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$defs":{"metadata":{"additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"enum":["live","candidate"]},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"candidate":{"$ref":"#/$defs/metadata"},"live":{"$ref":"#/$defs/metadata"},"relation":{"enum":["lineage_mismatch","candidate_older","candidate_newer","equal_serial"]},"serial_delta":{"type":["integer","null"]}},"required":["live","candidate","relation","serial_delta"],"type":"object"}},{"id":"tf.state_file_metadata","title":"Project candidate Terraform state metadata","summary":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","description":"Read one restricted candidate .tfstate file and return metadata only. The filename must resolve beneath TF_STATE_CANDIDATE_DIR; symlink and traversal escapes fail closed.","kind":"script","risk":"low","side_effects":["Reads one candidate state file capped at 64 MiB.","Never emits state values or modifies the file."],"args":[{"name":"candidate_file","type":"string","required":true,"description":"Candidate .tfstate basename under TF_STATE_CANDIDATE_DIR.","validation":{"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,126}\\.tfstate$","max_length":135}}],"examples":[{"title":"Candidate metadata","args":{"candidate_file":"failed-upload.tfstate"}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"candidate"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_list","title":"terraform state list","summary":"List all resource addresses currently in state.","description":"List all resource addresses currently in state.","kind":"exec","risk":"low","side_effects":["Reads state file.","Read-only."],"args":[],"examples":[{"title":"State resources","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state list"]}},{"id":"tf.state_metadata","title":"Project live Terraform state metadata","summary":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","description":"Pull the current backend state and return only its format version, lineage, serial, Terraform version, and resource instance count. Resource values and outputs are never emitted or written to disk.","kind":"script","risk":"low","side_effects":["One read-only backend state pull.","Holds at most 64 MiB of raw state in process memory before projecting metadata."],"args":[],"examples":[{"title":"Current backend metadata","args":{}}],"search_terms":[],"output_schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"properties":{"lineage":{"type":"string"},"resource_instance_count":{"minimum":0,"type":"integer"},"serial":{"minimum":0,"type":"integer"},"source":{"const":"live"},"state_format_version":{"const":4},"terraform_version":{"type":"string"}},"required":["source","state_format_version","lineage","serial","terraform_version","resource_instance_count"],"type":"object"}},{"id":"tf.state_show","title":"terraform state show <address>","summary":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","description":"Show attributes of one resource in state. May contain secrets — relies on audit redaction.","kind":"exec","risk":"high","side_effects":["Reads state file.","Read-only — output may contain sensitive attributes; rely on redaction."],"args":[{"name":"address","type":"string","required":true,"description":"Resource address (e.g. 'aws_instance.api').","validation":{"pattern":"^[a-zA-Z0-9_.\\-\\[\\]\"]{1,256}$"}}],"examples":[{"title":"One resource","args":{"address":"aws_instance.api"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" state show ''\"$1\"''","emisar","{{ args.address }}"]}},{"id":"tf.validate","title":"terraform validate","summary":"Validate the workspace's HCL files. No state read or write.","description":"Validate the workspace's HCL files. No state read or write.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Validate","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" validate"]}},{"id":"tf.version","title":"terraform version","summary":"Show the CLI version + provider versions.","description":"Show the CLI version + provider versions.","kind":"exec","risk":"low","side_effects":["Forks the configured CLI.","Read-only."],"args":[],"examples":[{"title":"Version","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","cd \"$TF_DIR\" && \"${TF_BIN:-terraform}\" version"]}}]}]},{"id":"time-sync","name":"Chrony time sync diagnostics","version":"0.1.11","description":"Clock-sync state for Chrony hosts: tracking, sources, current time, drift estimate, timezone, plus fix actions (chronyc makestep, enable/disable NTP). Use when a host's clock is drifting (a common cause of TLS / auth / log-correlation bugs).","vendor":"emisar","homepage":"https://emisar.dev/packs/time-sync","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/time-sync","content_hash":"sha256:336ba47da1e68b561e4225441aa6866d0972d4c8abda94ccfe03e2a8818186d0","tarball_url":"https://registry.emisar.dev/v1/packs/time-sync/0.1.11/336ba47da1e68b561e4225441aa6866d0972d4c8abda94ccfe03e2a8818186d0/pack.tar.gz","requires":{"os":["linux"],"binaries":[]},"detect":{"binaries":[],"processes":["chronyd"],"ports":[]},"setup":{"summary":"Queries and adjusts Chrony and systemd time state on the local runner host — no credentials needed.","notes":["Read actions (timedatectl, chronyc tracking/sources, date) need no privileges.","For ntpd hosts, install the separate time-sync-ntpsec pack."],"host_access":[{"actions":["time.chronyc_makestep","time.timedatectl_set_ntp"],"requirement":"Step the system clock or change the host NTP setting as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-time-sync-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. These actions can abruptly step wall-clock time or change which daemon controls synchronization."}]}],"verify":"time.timedatectl"},"actions":[{"id":"time.chrony_sources","title":"chronyc sources -v","summary":"List NTP sources + reach + stratum + offset.","description":"List NTP sources + reach + stratum + offset.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony sources","args":{}}],"search_terms":["ntp servers"],"command":{"binary":"chronyc","argv":["sources","-v"]}},{"id":"time.chrony_tracking","title":"chronyc tracking","summary":"Show Chrony's view of clock drift, frequency, last update.","description":"Show Chrony's view of clock drift, frequency, last update.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony tracking","args":{}}],"search_terms":["clock drift","time skew","clock wrong","out of sync"],"command":{"binary":"chronyc","argv":["tracking"]}},{"id":"time.chronyc_makestep","title":"chronyc makestep","summary":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","description":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","kind":"exec","risk":"high","side_effects":["System clock jumps to NTP-synced time.","Apps observe a time discontinuity.","Cron jobs in the skipped window do NOT fire.","TLS cert validation may briefly fail mid-step."],"args":[],"examples":[{"title":"Force clock step","args":{}}],"search_terms":["force time sync","fix the clock"],"command":{"binary":"chronyc","argv":["makestep"]}},{"id":"time.date_now","title":"date -u","summary":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","description":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","kind":"exec","risk":"low","side_effects":["One date call.","Read-only."],"args":[],"examples":[{"title":"Now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","date -u '+%Y-%m-%dT%H:%M:%SZ utc'; date '+%Y-%m-%dT%H:%M:%S%z local %A'"]}},{"id":"time.timedatectl","title":"timedatectl status","summary":"Show current time, timezone, NTP-active state, RTC sync state.","description":"Show current time, timezone, NTP-active state, RTC sync state.","kind":"exec","risk":"low","side_effects":["One systemd-timesyncd query.","Read-only."],"args":[],"examples":[{"title":"Time + sync state","args":{}}],"search_terms":["clock wrong","time skew","clock drift"],"command":{"binary":"timedatectl","argv":["status"]}},{"id":"time.timedatectl_set_ntp","title":"timedatectl set-ntp <bool>","summary":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","description":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","kind":"exec","risk":"high","side_effects":["Enables/disables the NTP client.","When disabled, the clock will drift."],"args":[{"name":"enabled","type":"boolean","required":true,"description":"Enable (true) or disable (false) NTP."}],"examples":[{"title":"Enable NTP","args":{"enabled":true}}],"search_terms":[],"command":{"binary":"timedatectl","argv":["set-ntp","{{ args.enabled }}"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:cbc081cbc8ca509e2ccb7397c733ae93c908342605bcb225c12d805a2504abd3","tarball_url":"https://registry.emisar.dev/v1/packs/time-sync/0.1.10/cbc081cbc8ca509e2ccb7397c733ae93c908342605bcb225c12d805a2504abd3/pack.tar.gz","actions":[{"id":"time.chrony_sources","title":"chronyc sources -v","summary":"List NTP sources + reach + stratum + offset.","description":"List NTP sources + reach + stratum + offset.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony sources","args":{}}],"search_terms":["ntp servers"],"command":{"binary":"chronyc","argv":["sources","-v"]}},{"id":"time.chrony_tracking","title":"chronyc tracking","summary":"Show Chrony's view of clock drift, frequency, last update.","description":"Show Chrony's view of clock drift, frequency, last update.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony tracking","args":{}}],"search_terms":["clock drift","time skew","clock wrong","out of sync"],"command":{"binary":"chronyc","argv":["tracking"]}},{"id":"time.chronyc_makestep","title":"chronyc makestep","summary":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","description":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","kind":"exec","risk":"high","side_effects":["System clock jumps to NTP-synced time.","Apps observe a time discontinuity.","Cron jobs in the skipped window do NOT fire.","TLS cert validation may briefly fail mid-step."],"args":[],"examples":[{"title":"Force clock step","args":{}}],"search_terms":["force time sync","fix the clock"],"command":{"binary":"chronyc","argv":["makestep"]}},{"id":"time.date_now","title":"date -u","summary":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","description":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","kind":"exec","risk":"low","side_effects":["One date call.","Read-only."],"args":[],"examples":[{"title":"Now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","date -u '+%Y-%m-%dT%H:%M:%SZ utc'; date '+%Y-%m-%dT%H:%M:%S%z local %A'"]}},{"id":"time.timedatectl","title":"timedatectl status","summary":"Show current time, timezone, NTP-active state, RTC sync state.","description":"Show current time, timezone, NTP-active state, RTC sync state.","kind":"exec","risk":"low","side_effects":["One systemd-timesyncd query.","Read-only."],"args":[],"examples":[{"title":"Time + sync state","args":{}}],"search_terms":["clock wrong","time skew","clock drift"],"command":{"binary":"timedatectl","argv":["status"]}},{"id":"time.timedatectl_set_ntp","title":"timedatectl set-ntp <bool>","summary":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","description":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","kind":"exec","risk":"high","side_effects":["Enables/disables the NTP client.","When disabled, the clock will drift."],"args":[{"name":"enabled","type":"boolean","required":true,"description":"Enable (true) or disable (false) NTP."}],"examples":[{"title":"Enable NTP","args":{"enabled":true}}],"search_terms":[],"command":{"binary":"timedatectl","argv":["set-ntp","{{ args.enabled }}"]}}]},{"version":"0.1.9","content_hash":"sha256:717e790d5496ff76f9f5dad8fdb05aa08b476147d8e52a9a18579e14cf27f9b3","tarball_url":"https://registry.emisar.dev/v1/packs/time-sync/0.1.9/717e790d5496ff76f9f5dad8fdb05aa08b476147d8e52a9a18579e14cf27f9b3/pack.tar.gz","actions":[{"id":"time.chrony_sources","title":"chronyc sources -v","summary":"List NTP sources + reach + stratum + offset.","description":"List NTP sources + reach + stratum + offset.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony sources","args":{}}],"search_terms":["ntp servers"],"command":{"binary":"chronyc","argv":["sources","-v"]}},{"id":"time.chrony_tracking","title":"chronyc tracking","summary":"Show Chrony's view of clock drift, frequency, last update.","description":"Show Chrony's view of clock drift, frequency, last update.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony tracking","args":{}}],"search_terms":["clock drift","time skew","clock wrong","out of sync"],"command":{"binary":"chronyc","argv":["tracking"]}},{"id":"time.chronyc_makestep","title":"chronyc makestep","summary":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","description":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","kind":"exec","risk":"high","side_effects":["System clock jumps to NTP-synced time.","Apps observe a time discontinuity.","Cron jobs in the skipped window do NOT fire.","TLS cert validation may briefly fail mid-step."],"args":[],"examples":[{"title":"Force clock step","args":{}}],"search_terms":["force time sync","fix the clock"],"command":{"binary":"chronyc","argv":["makestep"]}},{"id":"time.date_now","title":"date -u","summary":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","description":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","kind":"exec","risk":"low","side_effects":["One date call.","Read-only."],"args":[],"examples":[{"title":"Now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","date -u '+%Y-%m-%dT%H:%M:%SZ utc'; date '+%Y-%m-%dT%H:%M:%S%z local %A'"]}},{"id":"time.timedatectl","title":"timedatectl status","summary":"Show current time, timezone, NTP-active state, RTC sync state.","description":"Show current time, timezone, NTP-active state, RTC sync state.","kind":"exec","risk":"low","side_effects":["One systemd-timesyncd query.","Read-only."],"args":[],"examples":[{"title":"Time + sync state","args":{}}],"search_terms":["clock wrong","time skew","clock drift"],"command":{"binary":"timedatectl","argv":["status"]}},{"id":"time.timedatectl_set_ntp","title":"timedatectl set-ntp <bool>","summary":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","description":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","kind":"exec","risk":"high","side_effects":["Enables/disables the NTP client.","When disabled, the clock will drift."],"args":[{"name":"enabled","type":"boolean","required":true,"description":"Enable (true) or disable (false) NTP."}],"examples":[{"title":"Enable NTP","args":{"enabled":true}}],"search_terms":[],"command":{"binary":"timedatectl","argv":["set-ntp","{{ args.enabled }}"]}}]},{"version":"0.1.8","content_hash":"sha256:fa271a412ac92244b3a80c2ec8586c0e49ff2da5e83be19f958d61c2b72772d2","tarball_url":"https://registry.emisar.dev/v1/packs/time-sync/0.1.8/fa271a412ac92244b3a80c2ec8586c0e49ff2da5e83be19f958d61c2b72772d2/pack.tar.gz","actions":[{"id":"time.chrony_sources","title":"chronyc sources -v","summary":"List NTP sources + reach + stratum + offset.","description":"List NTP sources + reach + stratum + offset.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony sources","args":{}}],"search_terms":["ntp servers"],"command":{"binary":"chronyc","argv":["sources","-v"]}},{"id":"time.chrony_tracking","title":"chronyc tracking","summary":"Show Chrony's view of clock drift, frequency, last update.","description":"Show Chrony's view of clock drift, frequency, last update.","kind":"exec","risk":"low","side_effects":["One chrony query.","Read-only."],"args":[],"examples":[{"title":"Chrony tracking","args":{}}],"search_terms":["clock drift","time skew","clock wrong","out of sync"],"command":{"binary":"chronyc","argv":["tracking"]}},{"id":"time.chronyc_makestep","title":"chronyc makestep","summary":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","description":"Force chrony to step the system clock NOW instead of slewing. Use when drift exceeds slew tolerance and applications can't wait. Jumps in time can confuse cert validation, log timestamps, and event ordering.","kind":"exec","risk":"high","side_effects":["System clock jumps to NTP-synced time.","Apps observe a time discontinuity.","Cron jobs in the skipped window do NOT fire.","TLS cert validation may briefly fail mid-step."],"args":[],"examples":[{"title":"Force clock step","args":{}}],"search_terms":["force time sync","fix the clock"],"command":{"binary":"chronyc","argv":["makestep"]}},{"id":"time.date_now","title":"date -u","summary":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","description":"Show UTC + local time + day-of-week. Compare against the requester's clock to spot drift.","kind":"exec","risk":"low","side_effects":["One date call.","Read-only."],"args":[],"examples":[{"title":"Now","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","date -u '+%Y-%m-%dT%H:%M:%SZ utc'; date '+%Y-%m-%dT%H:%M:%S%z local %A'"]}},{"id":"time.ntpq_peers","title":"ntpq -pn","summary":"List the NTP peer table (for systems still using ntpd rather than chrony).","description":"List the NTP peer table (for systems still using ntpd rather than chrony).","kind":"exec","risk":"low","side_effects":["One ntpq query.","Read-only."],"args":[],"examples":[{"title":"ntpd peers","args":{}}],"search_terms":[],"command":{"binary":"ntpq","argv":["-pn"]}},{"id":"time.timedatectl","title":"timedatectl status","summary":"Show current time, timezone, NTP-active state, RTC sync state.","description":"Show current time, timezone, NTP-active state, RTC sync state.","kind":"exec","risk":"low","side_effects":["One systemd-timesyncd query.","Read-only."],"args":[],"examples":[{"title":"Time + sync state","args":{}}],"search_terms":["clock wrong","time skew","clock drift"],"command":{"binary":"timedatectl","argv":["status"]}},{"id":"time.timedatectl_set_ntp","title":"timedatectl set-ntp <bool>","summary":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","description":"Enable or disable NTP synchronization. Disabling is rare — primarily for offline testing.","kind":"exec","risk":"high","side_effects":["Enables/disables the NTP client.","When disabled, the clock will drift."],"args":[{"name":"enabled","type":"boolean","required":true,"description":"Enable (true) or disable (false) NTP."}],"examples":[{"title":"Enable NTP","args":{"enabled":true}}],"search_terms":[],"command":{"binary":"timedatectl","argv":["set-ntp","{{ args.enabled }}"]}}]}]},{"id":"time-sync-ntpsec","name":"NTPsec time sync diagnostics","version":"0.1.1","description":"NTPsec peer visibility for hosts that run ntpd rather than Chrony. Keep this backend-specific pack off Chrony hosts so the catalog reflects executable capabilities instead of mutually exclusive time daemons.","vendor":"emisar","homepage":"https://emisar.dev/packs/time-sync-ntpsec","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/time-sync-ntpsec","content_hash":"sha256:5d018673b2f82e0b5711dbfd2379e008797d5567feea198976824e91bd591925","tarball_url":"https://registry.emisar.dev/v1/packs/time-sync-ntpsec/0.1.1/5d018673b2f82e0b5711dbfd2379e008797d5567feea198976824e91bd591925/pack.tar.gz","requires":{"os":["linux"],"binaries":["ntpq"]},"detect":{"binaries":[],"processes":["ntpd"],"ports":[]},"setup":{"summary":"Query the local NTPsec daemon with ntpq; no credentials are needed.","notes":["Install only on hosts that run NTPsec/ntpd. Chrony hosts use the time-sync pack."],"verify":"time.ntpq_peers"},"actions":[{"id":"time.ntpq_peers","title":"ntpq -pn","summary":"List the NTPsec peer table with numeric addresses.","description":"List the NTPsec peer table with numeric addresses.","kind":"exec","risk":"low","side_effects":["One ntpq query.","Read-only."],"args":[],"examples":[{"title":"NTPsec peers","args":{}}],"search_terms":[],"command":{"binary":"ntpq","argv":["-pn"]}}],"previous_versions":[{"version":"0.1.0","content_hash":"sha256:7649604b9cb0bc2e8810155b160ccb1778982b526a0a66f954d32a76084d15f9","tarball_url":"https://registry.emisar.dev/v1/packs/time-sync-ntpsec/0.1.0/7649604b9cb0bc2e8810155b160ccb1778982b526a0a66f954d32a76084d15f9/pack.tar.gz","actions":[{"id":"time.ntpq_peers","title":"ntpq -pn","summary":"List the NTPsec peer table with numeric addresses.","description":"List the NTPsec peer table with numeric addresses.","kind":"exec","risk":"low","side_effects":["One ntpq query.","Read-only."],"args":[],"examples":[{"title":"NTPsec peers","args":{}}],"search_terms":[],"command":{"binary":"ntpq","argv":["-pn"]}}]}]},{"id":"traefik","name":"Traefik ingress / reverse proxy","version":"0.1.22","description":"Read-only visibility into a Traefik (v2/v3) edge router over its HTTP API: the overview, entrypoints, and the full HTTP/TCP/UDP router + service + middleware inventory (each carrying its status and error list, so you can see which router is broken), a compact per-service health summary, plus a per-host readiness check that joins the router and service views into one cutover-preflight verdict, the raw dynamic-config dump, version, liveness ping, and Prometheus metrics. ACME/Let's Encrypt certificate state is read from the on-disk acme.json (no API exposes it), and access-log 4xx/5xx tails mirror the nginx pack. Default API at http://127.0.0.1:8080 (api.insecure mode); override via TRAEFIK_URL.","vendor":"emisar","homepage":"https://emisar.dev/packs/traefik","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/traefik","content_hash":"sha256:48f87d035955de6bc6416f22fb6361b61072fbd4367161b4666d995810b0e9dc","tarball_url":"https://registry.emisar.dev/v1/packs/traefik/0.1.22/48f87d035955de6bc6416f22fb6361b61072fbd4367161b4666d995810b0e9dc/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl","jq","openssl"]},"detect":{"binaries":[],"processes":["traefik"],"ports":[8080]},"setup":{"summary":"The API actions call the Traefik HTTP API at `$TRAEFIK_URL` via curl on the runner host. The OSS API is read-only (GET-only) by design. ACME cert state and access logs are read from local files, not the API.","env":[{"name":"TRAEFIK_URL","description":"Base URL of the Traefik API entrypoint — scheme, host, port. In api.insecure mode this is the dashboard entrypoint on :8080; in production it is whatever entrypoint your api@internal router binds.","default":"http://127.0.0.1:8080","example":"http://127.0.0.1:8080"},{"name":"TRAEFIK_PING_URL","description":"Base URL of the entrypoint that serves /ping. Defaults to `TRAEFIK_URL`; set it when liveness is deliberately separated from the API.","example":"http://127.0.0.1:8082"},{"name":"TRAEFIK_BASICAUTH","description":"Optional \"user:password\" for a production API behind a basicAuth middleware. Base64-encoded and sent as an Authorization header over curl stdin, so it never appears in the process arguments or audit log."},{"name":"TRAEFIK_INSECURE","description":"Set to \"true\" to skip TLS verification when the API is served over https with a self-signed certificate."},{"name":"TRAEFIK_ACCESS_LOG","description":"Where this host's Traefik access log lives, for the log_grep_* actions. Set it when the log is outside `/var/log/traefik` — the actions' own log_path argument is deliberately contained to that directory, so this is how the host administrator, rather than a caller, declares a non-standard location.","default":"/var/log/traefik/access.log","example":"/data/logs/traefik/access.log"}],"notes":["Any of `TRAEFIK_URL` / `TRAEFIK_PING_URL` / `TRAEFIK_BASICAUTH` / `TRAEFIK_INSECURE` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Enable the API to use this pack: --api=true (production, behind a router + auth) or --api.insecure=true (exposes it unauthenticated on the :8080 traefik entrypoint — dev only).","Every API action is a read-only GET. The OSS Traefik API has no write endpoints; config changes only happen through providers (file/docker/k8s), never the API.","Per-router health: each router/service object carries status (enabled | warning | disabled) and an error[] list. Filter for status != enabled to find broken routing. Services also expose serverStatus (per-backend UP/DOWN).","ACME certificate material lives only in the acme.json storage file, never the API.","/ping defaults to `TRAEFIK_URL` but is often moved to a dedicated entrypoint; set `TRAEFIK_PING_URL` without disturbing the API actions.","Logs outside `/var/log/traefik`: set `TRAEFIK_ACCESS_LOG` (and allowlist it in the runner's `execution.inherit_env`). The log_path argument stays contained to `/var/log/traefik` because a caller — including an LLM — supplies it; the environment is host-administrator state, and anyone who can set it can already read the file. If Traefik logs to stdout instead (no accessLog.filePath), no file exists to read at any path: query whichever store collects it, e.g. the victorialogs pack. For unrestricted `/var/log` access, install linux-core, whose name says so."],"host_access":[{"actions":["traefik.acme_domains","traefik.acme_cert_expiry","traefik.log_grep_4xx","traefik.log_grep_5xx"],"requirement":"Read Traefik's mode-0600 ACME storage and protected access log.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-traefik-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. The ACME file contains private keys and account material even though these actions project only certificate metadata."}]}],"verify":"traefik.version"},"actions":[{"id":"traefik.acme_cert_expiry","title":"ACME certificate expiry (from acme.json)","summary":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","description":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (public certificate fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Per-domain cert expiry","args":{}}],"search_terms":["expired","expiring soon","renewal failed"],"command":{"binary":"/bin/sh","argv":["-c","[ -r \"$1\" ] || { echo \"acme storage not readable: $1\" >&2; exit 1; }\nentries=$(jq -r 'to_entries[].value.Certificates[]? | \"\\(.domain.main) \\(.certificate)\"' \"$1\") || exit 1\nprintf '%s\\n' \"$entries\" | while read -r dom cert; do exp=$(printf '%s' \"$cert\" | base64 -d 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2); printf '%s\\texpires %s\\n' \"$dom\" \"${exp:-<unreadable>}\"; done\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.acme_domains","title":"ACME certificate domains (from acme.json)","summary":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","description":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (domain fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file. Common locations are /etc/traefik/acme.json or /letsencrypt/acme.json.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Domains with issued certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","jq -r 'to_entries[].value.Certificates[]? | (([.domain.main] + (.domain.sans // [])) | join(\", \"))' \"$1\"\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.entrypoints","title":"GET /api/entrypoints","summary":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","description":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All entrypoints + addresses","args":{}}],"search_terms":[]},{"id":"traefik.http_host_readiness","title":"Check whether a public host is live behind Traefik","summary":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read.","description":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read. Joins /api/http/routers and /api/http/services into ONE compact verdict: is there an enabled router matching Host(`<host>`), a healthy service behind it, and at least one UP backend? Returns \"host\", \"ready\" (true only when nothing is wrong), the matched router and resolved service (name/provider/status/errors), backend counts (up/down/total) with the DOWN backend URLs, and a \"failures\" list of operator-readable reasons: missing_router, router_not_enabled, router_errors, missing_service, service_not_enabled, service_errors, no_up_backends, backend_down. Use this before a DNS/origin cutover instead of the raw 4 MiB inventory dumps.","kind":"script","risk":"low","side_effects":["Two read-only HTTP GETs to the Traefik API.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"The public host to check, as it appears in the router's Host(`…`) rule — a bare DNS name, no scheme/port/path (e.g. app.va1.example.com).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}}],"examples":[{"title":"Is app.va1.example.com live behind Traefik?","args":{"host":"app.va1.example.com"}},{"title":"Preflight a host before an origin cutover","args":{"host":"shop.example.com"}}],"search_terms":["site down","website unreachable","is the site up","website down"]},{"id":"traefik.http_middlewares","title":"GET /api/http/middlewares","summary":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","description":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP middlewares","args":{}}],"search_terms":[]},{"id":"traefik.http_routers","title":"GET /api/http/routers","summary":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","description":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP routers (+ status/error)","args":{}}],"search_terms":[]},{"id":"traefik.http_services","title":"GET /api/http/services","summary":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","description":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP services (+ serverStatus UP/DOWN)","args":{}}],"search_terms":[]},{"id":"traefik.http_services_summary","title":"List HTTP services, compact health summary","summary":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config.","description":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config. One row per service: name, provider, status, error_count + errors, backend counts (up/down/total), and the URLs of only the DOWN backends. Set only_unhealthy=true to return just the services that need attention (not \"enabled\", carrying errors, a DOWN backend, or a load-balancer with no UP backend). Use traefik.http_services for the full raw load-balancer config of a single service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[{"name":"only_unhealthy","type":"boolean","required":false,"default":false,"description":"When true, return only services that need attention — status not \"enabled\", with errors, with a DOWN backend, or a load-balancer with no UP backend. Default false returns every service."}],"examples":[{"title":"Compact health summary of every HTTP service","args":{}},{"title":"Only the services that need attention","args":{"only_unhealthy":true}}],"search_terms":[]},{"id":"traefik.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":["404 errors","client errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":4[0-9][0-9]| 4[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":["internal server error","bad gateway","500 errors","502 errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":5[0-9][0-9]| 5[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.metrics","title":"GET /metrics","summary":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","description":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik metrics endpoint.","Read-only."],"args":[],"examples":[{"title":"Prometheus metrics","args":{}}],"search_terms":[]},{"id":"traefik.overview","title":"GET /api/overview","summary":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","description":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Router/service/middleware counts + features","args":{}}],"search_terms":[]},{"id":"traefik.ping","title":"GET /ping","summary":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default). Set TRAEFIK_PING_URL when that entrypoint differs from the API.","description":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default). Set TRAEFIK_PING_URL when that entrypoint differs from the API.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik ping endpoint.","Read-only."],"args":[],"examples":[{"title":"Liveness check","args":{}}],"search_terms":[]},{"id":"traefik.rawdata","title":"GET /api/rawdata","summary":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","description":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Full live dynamic config + dependency graph","args":{}}],"search_terms":[]},{"id":"traefik.tcp_routers","title":"GET /api/tcp/routers","summary":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","description":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP routers","args":{}}],"search_terms":[]},{"id":"traefik.tcp_services","title":"GET /api/tcp/services","summary":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","description":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP services","args":{}}],"search_terms":[]},{"id":"traefik.udp_routers","title":"GET /api/udp/routers","summary":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","description":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All UDP routers","args":{}}],"search_terms":[]},{"id":"traefik.version","title":"GET /api/version","summary":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","description":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Version + codename","args":{}}],"search_terms":[]}],"previous_versions":[{"version":"0.1.19","content_hash":"sha256:c7ec5061fea62fc5df20ab14aa6f5b4b99f9184e383ba8c939513cfc9f79974a","tarball_url":"https://registry.emisar.dev/v1/packs/traefik/0.1.19/c7ec5061fea62fc5df20ab14aa6f5b4b99f9184e383ba8c939513cfc9f79974a/pack.tar.gz","actions":[{"id":"traefik.acme_cert_expiry","title":"ACME certificate expiry (from acme.json)","summary":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","description":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (public certificate fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Per-domain cert expiry","args":{}}],"search_terms":["expired","expiring soon","renewal failed"],"command":{"binary":"/bin/sh","argv":["-c","[ -r \"$1\" ] || { echo \"acme storage not readable: $1\" >&2; exit 1; }\nentries=$(jq -r 'to_entries[].value.Certificates[]? | \"\\(.domain.main) \\(.certificate)\"' \"$1\") || exit 1\nprintf '%s\\n' \"$entries\" | while read -r dom cert; do exp=$(printf '%s' \"$cert\" | base64 -d 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2); printf '%s\\texpires %s\\n' \"$dom\" \"${exp:-<unreadable>}\"; done\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.acme_domains","title":"ACME certificate domains (from acme.json)","summary":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","description":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (domain fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file. Common locations are /etc/traefik/acme.json or /letsencrypt/acme.json.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Domains with issued certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","jq -r 'to_entries[].value.Certificates[]? | (([.domain.main] + (.domain.sans // [])) | join(\", \"))' \"$1\"\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.entrypoints","title":"GET /api/entrypoints","summary":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","description":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All entrypoints + addresses","args":{}}],"search_terms":[]},{"id":"traefik.http_host_readiness","title":"Check whether a public host is live behind Traefik","summary":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read.","description":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read. Joins /api/http/routers and /api/http/services into ONE compact verdict: is there an enabled router matching Host(`<host>`), a healthy service behind it, and at least one UP backend? Returns \"host\", \"ready\" (true only when nothing is wrong), the matched router and resolved service (name/provider/status/errors), backend counts (up/down/total) with the DOWN backend URLs, and a \"failures\" list of operator-readable reasons: missing_router, router_not_enabled, router_errors, missing_service, service_not_enabled, service_errors, no_up_backends, backend_down. Use this before a DNS/origin cutover instead of the raw 4 MiB inventory dumps.","kind":"script","risk":"low","side_effects":["Two read-only HTTP GETs to the Traefik API.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"The public host to check, as it appears in the router's Host(`…`) rule — a bare DNS name, no scheme/port/path (e.g. app.va1.example.com).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}}],"examples":[{"title":"Is app.va1.example.com live behind Traefik?","args":{"host":"app.va1.example.com"}},{"title":"Preflight a host before an origin cutover","args":{"host":"shop.example.com"}}],"search_terms":["site down","website unreachable","is the site up","website down"]},{"id":"traefik.http_middlewares","title":"GET /api/http/middlewares","summary":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","description":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP middlewares","args":{}}],"search_terms":[]},{"id":"traefik.http_routers","title":"GET /api/http/routers","summary":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","description":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP routers (+ status/error)","args":{}}],"search_terms":[]},{"id":"traefik.http_services","title":"GET /api/http/services","summary":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","description":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP services (+ serverStatus UP/DOWN)","args":{}}],"search_terms":[]},{"id":"traefik.http_services_summary","title":"List HTTP services, compact health summary","summary":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config.","description":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config. One row per service: name, provider, status, error_count + errors, backend counts (up/down/total), and the URLs of only the DOWN backends. Set only_unhealthy=true to return just the services that need attention (not \"enabled\", carrying errors, a DOWN backend, or a load-balancer with no UP backend). Use traefik.http_services for the full raw load-balancer config of a single service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[{"name":"only_unhealthy","type":"boolean","required":false,"default":false,"description":"When true, return only services that need attention — status not \"enabled\", with errors, with a DOWN backend, or a load-balancer with no UP backend. Default false returns every service."}],"examples":[{"title":"Compact health summary of every HTTP service","args":{}},{"title":"Only the services that need attention","args":{"only_unhealthy":true}}],"search_terms":[]},{"id":"traefik.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":["404 errors","client errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":4[0-9][0-9]| 4[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":["internal server error","bad gateway","500 errors","502 errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":5[0-9][0-9]| 5[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.metrics","title":"GET /metrics","summary":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","description":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik metrics endpoint.","Read-only."],"args":[],"examples":[{"title":"Prometheus metrics","args":{}}],"search_terms":[]},{"id":"traefik.overview","title":"GET /api/overview","summary":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","description":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Router/service/middleware counts + features","args":{}}],"search_terms":[]},{"id":"traefik.ping","title":"GET /ping","summary":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default). Set TRAEFIK_PING_URL when that entrypoint differs from the API.","description":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default). Set TRAEFIK_PING_URL when that entrypoint differs from the API.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik ping endpoint.","Read-only."],"args":[],"examples":[{"title":"Liveness check","args":{}}],"search_terms":[]},{"id":"traefik.rawdata","title":"GET /api/rawdata","summary":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","description":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Full live dynamic config + dependency graph","args":{}}],"search_terms":[]},{"id":"traefik.tcp_routers","title":"GET /api/tcp/routers","summary":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","description":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP routers","args":{}}],"search_terms":[]},{"id":"traefik.tcp_services","title":"GET /api/tcp/services","summary":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","description":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP services","args":{}}],"search_terms":[]},{"id":"traefik.udp_routers","title":"GET /api/udp/routers","summary":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","description":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All UDP routers","args":{}}],"search_terms":[]},{"id":"traefik.version","title":"GET /api/version","summary":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","description":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Version + codename","args":{}}],"search_terms":[]}]},{"version":"0.1.16","content_hash":"sha256:e53ab8df709c4840f98ee2832d5f1425b0d5f1a7197668c7effba4324d5ec354","tarball_url":"https://registry.emisar.dev/v1/packs/traefik/0.1.16/e53ab8df709c4840f98ee2832d5f1425b0d5f1a7197668c7effba4324d5ec354/pack.tar.gz","actions":[{"id":"traefik.acme_cert_expiry","title":"ACME certificate expiry (from acme.json)","summary":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","description":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (public certificate fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Per-domain cert expiry","args":{}}],"search_terms":["expired","expiring soon","renewal failed"],"command":{"binary":"/bin/sh","argv":["-c","[ -r \"$1\" ] || { echo \"acme storage not readable: $1\" >&2; exit 1; }\nentries=$(jq -r 'to_entries[].value.Certificates[]? | \"\\(.domain.main) \\(.certificate)\"' \"$1\") || exit 1\nprintf '%s\\n' \"$entries\" | while read -r dom cert; do exp=$(printf '%s' \"$cert\" | base64 -d 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2); printf '%s\\texpires %s\\n' \"$dom\" \"${exp:-<unreadable>}\"; done\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.acme_domains","title":"ACME certificate domains (from acme.json)","summary":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","description":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (domain fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file. Common locations are /etc/traefik/acme.json or /letsencrypt/acme.json.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Domains with issued certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","jq -r 'to_entries[].value.Certificates[]? | (([.domain.main] + (.domain.sans // [])) | join(\", \"))' \"$1\"\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.entrypoints","title":"GET /api/entrypoints","summary":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","description":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All entrypoints + addresses","args":{}}],"search_terms":[]},{"id":"traefik.http_host_readiness","title":"Check whether a public host is live behind Traefik","summary":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read.","description":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read. Joins /api/http/routers and /api/http/services into ONE compact verdict: is there an enabled router matching Host(`<host>`), a healthy service behind it, and at least one UP backend? Returns \"host\", \"ready\" (true only when nothing is wrong), the matched router and resolved service (name/provider/status/errors), backend counts (up/down/total) with the DOWN backend URLs, and a \"failures\" list of operator-readable reasons: missing_router, router_not_enabled, router_errors, missing_service, service_not_enabled, service_errors, no_up_backends, backend_down. Use this before a DNS/origin cutover instead of the raw 4 MiB inventory dumps.","kind":"script","risk":"low","side_effects":["Two read-only HTTP GETs to the Traefik API.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"The public host to check, as it appears in the router's Host(`…`) rule — a bare DNS name, no scheme/port/path (e.g. app.va1.example.com).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}}],"examples":[{"title":"Is app.va1.example.com live behind Traefik?","args":{"host":"app.va1.example.com"}},{"title":"Preflight a host before an origin cutover","args":{"host":"shop.example.com"}}],"search_terms":["site down","website unreachable","is the site up","website down"]},{"id":"traefik.http_middlewares","title":"GET /api/http/middlewares","summary":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","description":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP middlewares","args":{}}],"search_terms":[]},{"id":"traefik.http_routers","title":"GET /api/http/routers","summary":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","description":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP routers (+ status/error)","args":{}}],"search_terms":[]},{"id":"traefik.http_services","title":"GET /api/http/services","summary":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","description":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP services (+ serverStatus UP/DOWN)","args":{}}],"search_terms":[]},{"id":"traefik.http_services_summary","title":"List HTTP services, compact health summary","summary":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config.","description":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config. One row per service: name, provider, status, error_count + errors, backend counts (up/down/total), and the URLs of only the DOWN backends. Set only_unhealthy=true to return just the services that need attention (not \"enabled\", carrying errors, a DOWN backend, or a load-balancer with no UP backend). Use traefik.http_services for the full raw load-balancer config of a single service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[{"name":"only_unhealthy","type":"boolean","required":false,"default":false,"description":"When true, return only services that need attention — status not \"enabled\", with errors, with a DOWN backend, or a load-balancer with no UP backend. Default false returns every service."}],"examples":[{"title":"Compact health summary of every HTTP service","args":{}},{"title":"Only the services that need attention","args":{"only_unhealthy":true}}],"search_terms":[]},{"id":"traefik.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":["404 errors","client errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":4[0-9][0-9]| 4[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":["internal server error","bad gateway","500 errors","502 errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":5[0-9][0-9]| 5[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.metrics","title":"GET /metrics","summary":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","description":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik metrics endpoint.","Read-only."],"args":[],"examples":[{"title":"Prometheus metrics","args":{}}],"search_terms":[]},{"id":"traefik.overview","title":"GET /api/overview","summary":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","description":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Router/service/middleware counts + features","args":{}}],"search_terms":[]},{"id":"traefik.ping","title":"GET /ping","summary":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default). Set TRAEFIK_PING_URL when that entrypoint differs from the API.","description":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default). Set TRAEFIK_PING_URL when that entrypoint differs from the API.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik ping endpoint.","Read-only."],"args":[],"examples":[{"title":"Liveness check","args":{}}],"search_terms":[]},{"id":"traefik.rawdata","title":"GET /api/rawdata","summary":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","description":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Full live dynamic config + dependency graph","args":{}}],"search_terms":[]},{"id":"traefik.tcp_routers","title":"GET /api/tcp/routers","summary":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","description":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP routers","args":{}}],"search_terms":[]},{"id":"traefik.tcp_services","title":"GET /api/tcp/services","summary":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","description":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP services","args":{}}],"search_terms":[]},{"id":"traefik.udp_routers","title":"GET /api/udp/routers","summary":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","description":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All UDP routers","args":{}}],"search_terms":[]},{"id":"traefik.version","title":"GET /api/version","summary":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","description":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Version + codename","args":{}}],"search_terms":[]}]},{"version":"0.1.15","content_hash":"sha256:dd21a522f92e1bf26e5f9ff0c567a89cbd75eb56b8ff149b5c2eac28560288b2","tarball_url":"https://registry.emisar.dev/v1/packs/traefik/0.1.15/dd21a522f92e1bf26e5f9ff0c567a89cbd75eb56b8ff149b5c2eac28560288b2/pack.tar.gz","actions":[{"id":"traefik.acme_cert_expiry","title":"ACME certificate expiry (from acme.json)","summary":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","description":"Show each ACME/Let's Encrypt certificate in acme.json with its domain and notAfter expiry date. Decodes only the public certificate (base64 PEM) through openssl — never touches the private key. Traefik auto-renews 30 days out, so anything closer than that which is NOT renewing is the thing to investigate. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (public certificate fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Per-domain cert expiry","args":{}}],"search_terms":["expired","expiring soon","renewal failed"],"command":{"binary":"/bin/sh","argv":["-c","[ -r \"$1\" ] || { echo \"acme storage not readable: $1\" >&2; exit 1; }\nentries=$(jq -r 'to_entries[].value.Certificates[]? | \"\\(.domain.main) \\(.certificate)\"' \"$1\") || exit 1\nprintf '%s\\n' \"$entries\" | while read -r dom cert; do exp=$(printf '%s' \"$cert\" | base64 -d 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2); printf '%s\\texpires %s\\n' \"$dom\" \"${exp:-<unreadable>}\"; done\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.acme_domains","title":"ACME certificate domains (from acme.json)","summary":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","description":"List the domains (CN + SANs) Traefik holds ACME/Let's Encrypt certificates for, read from the on-disk acme.json storage (no API exposes cert state). Reads only the domain fields — never the certificate or private-key material. Use to confirm a hostname actually has an issued cert.","kind":"exec","risk":"low","side_effects":["Reads the acme.json storage file (domain fields only).","Read-only."],"args":[{"name":"acme_path","type":"string","required":false,"default":"/etc/traefik/acme.json","description":"Path to Traefik's ACME storage file. Common locations are /etc/traefik/acme.json or /letsencrypt/acme.json.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/traefik","/letsencrypt"]}}],"examples":[{"title":"Domains with issued certs","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","jq -r 'to_entries[].value.Certificates[]? | (([.domain.main] + (.domain.sans // [])) | join(\", \"))' \"$1\"\n","emisar","{{ args.acme_path }}"]}},{"id":"traefik.entrypoints","title":"GET /api/entrypoints","summary":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","description":"List all configured entrypoints — name, listen address/port, and transport settings (timeouts, HTTP/2, TLS defaults). Use to confirm the front door is listening where you expect (web :80, websecure :443, etc.).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All entrypoints + addresses","args":{}}],"search_terms":[]},{"id":"traefik.http_host_readiness","title":"Check whether a public host is live behind Traefik","summary":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read.","description":"Check a single public host's end-to-end readiness through Traefik — the cutover preflight read. Joins /api/http/routers and /api/http/services into ONE compact verdict: is there an enabled router matching Host(`<host>`), a healthy service behind it, and at least one UP backend? Returns \"host\", \"ready\" (true only when nothing is wrong), the matched router and resolved service (name/provider/status/errors), backend counts (up/down/total) with the DOWN backend URLs, and a \"failures\" list of operator-readable reasons: missing_router, router_not_enabled, router_errors, missing_service, service_not_enabled, service_errors, no_up_backends, backend_down. Use this before a DNS/origin cutover instead of the raw 4 MiB inventory dumps.","kind":"script","risk":"low","side_effects":["Two read-only HTTP GETs to the Traefik API.","Read-only."],"args":[{"name":"host","type":"string","required":true,"description":"The public host to check, as it appears in the router's Host(`…`) rule — a bare DNS name, no scheme/port/path (e.g. app.va1.example.com).","validation":{"pattern":"^[a-zA-Z0-9.\\-]{1,253}$"}}],"examples":[{"title":"Is app.va1.example.com live behind Traefik?","args":{"host":"app.va1.example.com"}},{"title":"Preflight a host before an origin cutover","args":{"host":"shop.example.com"}}],"search_terms":["site down","website unreachable","is the site up","website down"]},{"id":"traefik.http_middlewares","title":"GET /api/http/middlewares","summary":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","description":"List every HTTP middleware (auth, rate-limit, headers, redirects, retries, circuit-breaker, etc.) with its config, status, and error[]. Use to confirm a middleware is configured as expected and not in error.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP middlewares","args":{}}],"search_terms":[]},{"id":"traefik.http_routers","title":"GET /api/http/routers","summary":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","description":"List every HTTP router with its rule, entrypoints, service, middlewares, TLS config, and — critically — its status (\"enabled\" | \"warning\" | \"disabled\") and error[] list. To find broken routing, look for any router whose status is not \"enabled\" and read its error[]. Names are \"<name>@<provider>\" (e.g. my-router@docker).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP routers (+ status/error)","args":{}}],"search_terms":[]},{"id":"traefik.http_services","title":"GET /api/http/services","summary":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","description":"List every HTTP service with its load-balancer config, status, error[], and serverStatus — a per-backend map of URL to \"UP\"/\"DOWN\". This is the \"which upstream is down?\" read: a service with a DOWN server (or a non-\"enabled\" status) is failing health checks.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All HTTP services (+ serverStatus UP/DOWN)","args":{}}],"search_terms":[]},{"id":"traefik.http_services_summary","title":"List HTTP services, compact health summary","summary":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config.","description":"List every HTTP service as a compact, name-sorted health summary — the preflight-sized view of /api/http/services without its multi-megabyte load-balancer config. One row per service: name, provider, status, error_count + errors, backend counts (up/down/total), and the URLs of only the DOWN backends. Set only_unhealthy=true to return just the services that need attention (not \"enabled\", carrying errors, a DOWN backend, or a load-balancer with no UP backend). Use traefik.http_services for the full raw load-balancer config of a single service.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[{"name":"only_unhealthy","type":"boolean","required":false,"default":false,"description":"When true, return only services that need attention — status not \"enabled\", with errors, with a DOWN backend, or a load-balancer with no UP backend. Default false returns every service."}],"examples":[{"title":"Compact health summary of every HTTP service","args":{}},{"title":"Only the services that need attention","args":{"only_unhealthy":true}}],"search_terms":[]},{"id":"traefik.log_grep_4xx","title":"Recent 4xx responses from access log","summary":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 4xx responses and tail the most recent. Matches both the JSON format (DownstreamStatus field) and the default CLF format (status code after the request line). Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 4xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 4xx","args":{}}],"search_terms":["404 errors","client errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":4[0-9][0-9]| 4[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.log_grep_5xx","title":"Recent 5xx responses from access log","summary":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","description":"Grep the Traefik access log for 5xx responses and tail the most recent — the front-door view of backend failures. Matches both the JSON format (DownstreamStatus field) and the default CLF format. Needs an access log on disk, which Traefik writes only when accessLog.filePath is set; when it logs to stdout instead, query whichever log store collects it. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Traefik access log.","Read-only."],"args":[{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent 5xx lines to return.","validation":{"min":1,"max":5000}},{"name":"log_path","type":"string","required":false,"description":"Access log path. Omit to use $TRAEFIK_ACCESS_LOG, else /var/log/traefik/access.log. Constrained to /var/log/traefik — a host whose logs live elsewhere declares that in TRAEFIK_ACCESS_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/traefik/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/traefik"]}}],"examples":[{"title":"Last 100 5xx","args":{}}],"search_terms":["internal server error","bad gateway","500 errors","502 errors"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TRAEFIK_ACCESS_LOG:-/var/log/traefik/access.log}\"\n[ -r \"$log\" ] || { echo \"access log not readable: $log\" >&2; exit 1; }\ngrep -E '(\"DownstreamStatus\":5[0-9][0-9]| 5[0-9][0-9] )' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"traefik.metrics","title":"GET /metrics","summary":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","description":"Show Prometheus metrics in text exposition format (requires --metrics.prometheus=true): per-entrypoint/router/service request counts, durations, open connections, and TLS cert expiry gauges. Served on the traefik entrypoint (:8080) by default unless metrics.prometheus.entryPoint moves it.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik metrics endpoint.","Read-only."],"args":[],"examples":[{"title":"Prometheus metrics","args":{}}],"search_terms":[]},{"id":"traefik.overview","title":"GET /api/overview","summary":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","description":"Show dashboard summary — counts of HTTP/TCP/UDP routers, services, and middlewares by state (enabled/warning/errored), enabled providers, and which features (metrics, tracing) are on. The fastest \"is anything broken?\" read before drilling into the per-router inventory.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Router/service/middleware counts + features","args":{}}],"search_terms":[]},{"id":"traefik.ping","title":"GET /ping","summary":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default, unless moved to a dedicated one — point TRAEFIK_URL at it then).","description":"Check liveness. Returns 200 with body \"OK\" when healthy, or the configured terminating status (default 503) during graceful shutdown. Requires --ping=true; served on the ping entrypoint (the traefik entrypoint / :8080 by default, unless moved to a dedicated one — point TRAEFIK_URL at it then).","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik ping endpoint.","Read-only."],"args":[],"examples":[{"title":"Liveness check","args":{}}],"search_terms":[]},{"id":"traefik.rawdata","title":"GET /api/rawdata","summary":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","description":"Show the complete dynamic configuration as Traefik currently sees it — all routers, services, and middlewares across HTTP/TCP/UDP, each with its errors, plus the \"usedBy\" dependency graph tying routers to services and middlewares. The single most complete read for \"what is the actual live config and what depends on what?\". Larger than the per-kind endpoints.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Full live dynamic config + dependency graph","args":{}}],"search_terms":[]},{"id":"traefik.tcp_routers","title":"GET /api/tcp/routers","summary":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","description":"List every TCP router with its rule (HostSNI/...), entrypoints, service, TLS passthrough config, status, and error[]. Use for TCP/SNI routing (databases, message brokers, raw TLS) the same way http_routers covers HTTP.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP routers","args":{}}],"search_terms":[]},{"id":"traefik.tcp_services","title":"GET /api/tcp/services","summary":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","description":"List every TCP service with its load-balancer/weighted config, status, and error[]. The TCP counterpart to http_services.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All TCP services","args":{}}],"search_terms":[]},{"id":"traefik.udp_routers","title":"GET /api/udp/routers","summary":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","description":"List every UDP router (and its service binding) with status and error[]. Use for UDP entrypoints (DNS, QUIC, syslog) routing visibility. Pair with /api/udp/services via rawdata if you need the service side.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"All UDP routers","args":{}}],"search_terms":[]},{"id":"traefik.version","title":"GET /api/version","summary":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","description":"Show Traefik version, codename, and build/start date. Use to confirm which release is running (v2 vs v3 behaviour) and that the API answers.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Traefik API.","Read-only."],"args":[],"examples":[{"title":"Version + codename","args":{}}],"search_terms":[]}]}]},{"id":"typesense","name":"Typesense search","version":"0.1.18","description":"Read-only diagnostics for a Typesense search node over its HTTP API: health and node/raft state, per-endpoint request stats and system metrics, the collection catalog and individual schemas, API-key metadata, and a tail of slow requests from the server log. One admin API key, streamed over curl stdin, unlocks the stats/metrics/debug endpoints a search-only key cannot read.","vendor":"emisar","homepage":"https://emisar.dev/packs/typesense","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/typesense","content_hash":"sha256:be176eb7b22df09bb15d8871d0480005641b33130d71ba37a230fbe33aa683bb","tarball_url":"https://registry.emisar.dev/v1/packs/typesense/0.1.18/be176eb7b22df09bb15d8871d0480005641b33130d71ba37a230fbe33aa683bb/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["typesense-server"],"ports":[8108]},"setup":{"summary":"Every action calls the Typesense HTTP API at `$TYPESENSE_URL` via curl on the runner host, or tails the server log. The admin API key is read from `$TYPESENSE_API_KEY` and sent as X-TYPESENSE-API-KEY over curl stdin, so it never appears in the process arguments or the audit log.","env":[{"name":"TYPESENSE_URL","description":"Base URL of the Typesense node — scheme, host, and port. Each action appends its path (e.g. /collections, /stats.json).","default":"http://127.0.0.1:8108","example":"http://typesense:8108"},{"name":"TYPESENSE_API_KEY","description":"Admin API key; sent as X-TYPESENSE-API-KEY over curl stdin, never argv. Most diagnostic endpoints need the admin key — a search-only key cannot read stats/metrics/debug."},{"name":"TYPESENSE_LOG","description":"Where this host's Typesense server log lives, for slow_requests. Set it when the log is outside `/var/log/typesense` — slow_requests' own log_path argument is deliberately contained to that directory, so this is how the host administrator, rather than a caller, declares a non-standard location.","default":"/var/log/typesense/typesense.log","example":"/data/logs/typesense/typesense.log"}],"notes":["Any of `TYPESENSE_URL` / `TYPESENSE_API_KEY` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Every action is a read-only GET. /health needs no key; the rest expect the admin key in `TYPESENSE_API_KEY`.","Mutating operations are deliberately excluded: POST /config, /operations/snapshot, /operations/vote, /operations/db/compact, and /operations/cache/clear are not part of this pack.","Logs outside `/var/log/typesense`: set `TYPESENSE_LOG` (and allowlist it in the runner's `execution.inherit_env`). slow_requests' log_path argument stays contained to `/var/log/typesense` because a caller supplies it; the environment is host-administrator state. For unrestricted `/var/log` access, install linux-core, whose name says so.","Typesense has no slow-query endpoint — slow requests are written to the server log (enable with --log-slow-requests-time-ms) and read via the slow_requests action."],"host_access":[{"actions":["typesense.slow_requests"],"requirement":"Read the protected Typesense log across daemon restarts and log rotation.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-typesense-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root","sudo test -r /var/log/typesense/typesense.log"],"impact":"Every Emisar action on this runner executes as root. The Typesense log can contain request paths, timings, and other application data."}]}],"verify":"typesense.health"},"actions":[{"id":"typesense.collection","title":"GET /collections/{name}","summary":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","description":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections/{name} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$"}}],"examples":[{"title":"Schema for the \"products\" collection","args":{"name":"products"}}],"search_terms":[]},{"id":"typesense.collections","title":"GET /collections","summary":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","description":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"List all collections","args":{}}],"search_terms":[]},{"id":"typesense.debug","title":"GET /debug","summary":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","description":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /debug endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Read version and raft state","args":{}}],"search_terms":[]},{"id":"typesense.health","title":"GET /health","summary":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","description":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check node health","args":{}}],"search_terms":["search down","out of memory","out of disk","writes rejected"]},{"id":"typesense.keys","title":"GET /keys","summary":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","description":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /keys endpoint.","Read-only — never writes or mutates data.","Returns key metadata only (prefixes and scopes); secrets are not exposed."],"args":[],"examples":[{"title":"List API key metadata","args":{}}],"search_terms":[]},{"id":"typesense.metrics","title":"GET /metrics.json","summary":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","description":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /metrics.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current system/process metrics","args":{}}],"search_terms":[]},{"id":"typesense.slow_requests","title":"Recent slow requests from the server log","summary":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","description":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","kind":"exec","risk":"medium","side_effects":["Reads the Typesense server log file.","Read-only."],"args":[{"name":"log_path","type":"string","required":false,"description":"Typesense server log path. Omit to use $TYPESENSE_LOG, else /var/log/typesense/typesense.log. Constrained to /var/log/typesense — a host whose logs live elsewhere declares that in TYPESENSE_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/typesense/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/typesense"]}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent slow-request lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 slow requests","args":{}}],"search_terms":["slow queries"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TYPESENSE_LOG:-/var/log/typesense/typesense.log}\"\n[ -r \"$log\" ] || { echo \"server log not readable: $log\" >&2; exit 1; }\ngrep -F 'SLOW REQUEST' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"typesense.stats","title":"GET /stats.json","summary":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","description":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /stats.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current per-endpoint request stats","args":{}}],"search_terms":["slow searches"]}],"previous_versions":[{"version":"0.1.17","content_hash":"sha256:058acb70fc492990919c9b8611700d908cd4997f7f4136dd6650562520a0473e","tarball_url":"https://registry.emisar.dev/v1/packs/typesense/0.1.17/058acb70fc492990919c9b8611700d908cd4997f7f4136dd6650562520a0473e/pack.tar.gz","actions":[{"id":"typesense.collection","title":"GET /collections/{name}","summary":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","description":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections/{name} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$"}}],"examples":[{"title":"Schema for the \"products\" collection","args":{"name":"products"}}],"search_terms":[]},{"id":"typesense.collections","title":"GET /collections","summary":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","description":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"List all collections","args":{}}],"search_terms":[]},{"id":"typesense.debug","title":"GET /debug","summary":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","description":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /debug endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Read version and raft state","args":{}}],"search_terms":[]},{"id":"typesense.health","title":"GET /health","summary":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","description":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check node health","args":{}}],"search_terms":["search down","out of memory","out of disk","writes rejected"]},{"id":"typesense.keys","title":"GET /keys","summary":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","description":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /keys endpoint.","Read-only — never writes or mutates data.","Returns key metadata only (prefixes and scopes); secrets are not exposed."],"args":[],"examples":[{"title":"List API key metadata","args":{}}],"search_terms":[]},{"id":"typesense.metrics","title":"GET /metrics.json","summary":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","description":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /metrics.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current system/process metrics","args":{}}],"search_terms":[]},{"id":"typesense.slow_requests","title":"Recent slow requests from the server log","summary":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","description":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Typesense server log file.","Read-only."],"args":[{"name":"log_path","type":"string","required":false,"description":"Typesense server log path. Omit to use $TYPESENSE_LOG, else /var/log/typesense/typesense.log. Constrained to /var/log/typesense — a host whose logs live elsewhere declares that in TYPESENSE_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/typesense/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/typesense"]}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent slow-request lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 slow requests","args":{}}],"search_terms":["slow queries"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TYPESENSE_LOG:-/var/log/typesense/typesense.log}\"\n[ -r \"$log\" ] || { echo \"server log not readable: $log\" >&2; exit 1; }\ngrep -F 'SLOW REQUEST' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"typesense.stats","title":"GET /stats.json","summary":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","description":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /stats.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current per-endpoint request stats","args":{}}],"search_terms":["slow searches"]}]},{"version":"0.1.14","content_hash":"sha256:f7f67d9faf2484223f6790c182c0bae6772cfede749144169e375833b45a6bfe","tarball_url":"https://registry.emisar.dev/v1/packs/typesense/0.1.14/f7f67d9faf2484223f6790c182c0bae6772cfede749144169e375833b45a6bfe/pack.tar.gz","actions":[{"id":"typesense.collection","title":"GET /collections/{name}","summary":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","description":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections/{name} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$"}}],"examples":[{"title":"Schema for the \"products\" collection","args":{"name":"products"}}],"search_terms":[]},{"id":"typesense.collections","title":"GET /collections","summary":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","description":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"List all collections","args":{}}],"search_terms":[]},{"id":"typesense.debug","title":"GET /debug","summary":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","description":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /debug endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Read version and raft state","args":{}}],"search_terms":[]},{"id":"typesense.health","title":"GET /health","summary":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","description":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check node health","args":{}}],"search_terms":["search down","out of memory","out of disk","writes rejected"]},{"id":"typesense.keys","title":"GET /keys","summary":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","description":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /keys endpoint.","Read-only — never writes or mutates data.","Returns key metadata only (prefixes and scopes); secrets are not exposed."],"args":[],"examples":[{"title":"List API key metadata","args":{}}],"search_terms":[]},{"id":"typesense.metrics","title":"GET /metrics.json","summary":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","description":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /metrics.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current system/process metrics","args":{}}],"search_terms":[]},{"id":"typesense.slow_requests","title":"Recent slow requests from the server log","summary":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","description":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Typesense server log file.","Read-only."],"args":[{"name":"log_path","type":"string","required":false,"description":"Typesense server log path. Omit to use $TYPESENSE_LOG, else /var/log/typesense/typesense.log. Constrained to /var/log/typesense — a host whose logs live elsewhere declares that in TYPESENSE_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/typesense/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/typesense"]}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent slow-request lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 slow requests","args":{}}],"search_terms":["slow queries"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TYPESENSE_LOG:-/var/log/typesense/typesense.log}\"\n[ -r \"$log\" ] || { echo \"server log not readable: $log\" >&2; exit 1; }\ngrep -F 'SLOW REQUEST' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"typesense.stats","title":"GET /stats.json","summary":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","description":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /stats.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current per-endpoint request stats","args":{}}],"search_terms":["slow searches"]}]},{"version":"0.1.11","content_hash":"sha256:ed658ddc407f09e9f0f15315f61e5a0a80c7b080e0fff58394e7b9f45f352f86","tarball_url":"https://registry.emisar.dev/v1/packs/typesense/0.1.11/ed658ddc407f09e9f0f15315f61e5a0a80c7b080e0fff58394e7b9f45f352f86/pack.tar.gz","actions":[{"id":"typesense.collection","title":"GET /collections/{name}","summary":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","description":"Return the schema and document count for a single collection by name. Use when you already know the collection and want just its definition. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections/{name} endpoint.","Read-only — never writes or mutates data."],"args":[{"name":"name","type":"string","required":true,"description":"Collection name.","validation":{"pattern":"^[A-Za-z0-9._-]{1,128}$"}}],"examples":[{"title":"Schema for the \"products\" collection","args":{"name":"products"}}],"search_terms":[]},{"id":"typesense.collections","title":"GET /collections","summary":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","description":"List all collections on the node with their full schemas and document counts. Use to inventory what is indexed and how big each collection is. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /collections endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"List all collections","args":{}}],"search_terms":[]},{"id":"typesense.debug","title":"GET /debug","summary":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","description":"Show node version and raft state. The \"state\" field reports this node's role in the cluster: 1 = LEADER, 4 = FOLLOWER. This is how you read which node is leader vs follower per node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /debug endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Read version and raft state","args":{}}],"search_terms":[]},{"id":"typesense.health","title":"GET /health","summary":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","description":"Check liveness for the Typesense node. Returns {\"ok\": true} when healthy, and surfaces resource-exhaustion states (out of memory, out of disk) when the node has stopped accepting writes. No API key required.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /health endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Check node health","args":{}}],"search_terms":["search down","out of memory","out of disk","writes rejected"]},{"id":"typesense.keys","title":"GET /keys","summary":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","description":"List API key metadata — the key prefix, description, scoped actions, and collections each key may access. The secret value is never returned; only which keys exist and what they are allowed to do. Sensitive: it discloses the set of credentials configured on the node. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /keys endpoint.","Read-only — never writes or mutates data.","Returns key metadata only (prefixes and scopes); secrets are not exposed."],"args":[],"examples":[{"title":"List API key metadata","args":{}}],"search_terms":[]},{"id":"typesense.metrics","title":"GET /metrics.json","summary":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","description":"Show system and process metrics for the node — CPU utilization, memory usage, and disk usage. Use to see whether the node is resource-constrained. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /metrics.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current system/process metrics","args":{}}],"search_terms":[]},{"id":"typesense.slow_requests","title":"Recent slow requests from the server log","summary":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","description":"Tail slow requests from the Typesense server log — slow requests are written to the server log prefixed \"SLOW REQUEST\" (enable with --log-slow-requests-time-ms). This greps the log for those lines and tails the most recent ones. Read-only.","kind":"exec","risk":"low","side_effects":["Reads the Typesense server log file.","Read-only."],"args":[{"name":"log_path","type":"string","required":false,"description":"Typesense server log path. Omit to use $TYPESENSE_LOG, else /var/log/typesense/typesense.log. Constrained to /var/log/typesense — a host whose logs live elsewhere declares that in TYPESENSE_LOG, which only the host administrator can set.","validation":{"pattern":"^/var/log/typesense/[A-Za-z0-9._/-]{1,128}$","allowed_prefixes":["/var/log/typesense"]}},{"name":"lines","type":"integer","required":false,"default":100,"description":"How many recent slow-request lines.","validation":{"min":1,"max":5000}}],"examples":[{"title":"Last 100 slow requests","args":{}}],"search_terms":["slow queries"],"command":{"binary":"/bin/sh","argv":["-c","log=\"$1\"\n[ -n \"$log\" ] || log=\"${TYPESENSE_LOG:-/var/log/typesense/typesense.log}\"\n[ -r \"$log\" ] || { echo \"server log not readable: $log\" >&2; exit 1; }\ngrep -F 'SLOW REQUEST' \"$log\" | tail -n {{ args.lines }}\n","emisar","{{ args.log_path? }}"]}},{"id":"typesense.stats","title":"GET /stats.json","summary":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","description":"Show per-endpoint request statistics over the last 10 seconds — requests-per-second counters and latency_ms breakdowns per API path. Use to see which endpoints are hot and how slow they are right now. Requires the admin API key.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the Typesense /stats.json endpoint.","Read-only — never writes or mutates data."],"args":[],"examples":[{"title":"Current per-endpoint request stats","args":{}}],"search_terms":["slow searches"]}]}],"retired_below":"0.1.3"},{"id":"vault","name":"HashiCorp Vault operations","version":"0.1.12","description":"Vault status, seal state, auth/audit/secret backends, mount listing, token & lease introspection, plus operator surface for incident response: revoke lease, revoke leases by prefix, operator step-down, emergency seal. Auth via VAULT_ADDR + VAULT_TOKEN on the runner host. Does NOT include unseal — that requires quorum and shouldn't be automated through a runner.","vendor":"emisar","homepage":"https://emisar.dev/packs/vault","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/vault","content_hash":"sha256:4c19af4b0766ce165ab9512a47e42365524971bafaf25773f2e5d8744dd96156","tarball_url":"https://registry.emisar.dev/v1/packs/vault/0.1.12/4c19af4b0766ce165ab9512a47e42365524971bafaf25773f2e5d8744dd96156/pack.tar.gz","requires":{"os":["linux"],"binaries":["vault"]},"detect":{"binaries":[],"processes":["vault"],"ports":[8200]},"setup":{"summary":"The vault CLI reads the server address and auth token from `VAULT_ADDR` and `VAULT_TOKEN` on the runner host.","env":[{"name":"VAULT_ADDR","required":true,"description":"Vault API address, including scheme.","example":"https://vault.internal:8200"},{"name":"VAULT_TOKEN","description":"Token to authenticate with. Required unless a `~/.vault-token` file is present on the runner host."}],"notes":["Alternative to `VAULT_TOKEN`: a `~/.vault-token` file (written by `vault login`) on the runner host — read from disk, so it needs no `inherit_env` entry.","The token's policies gate every action; the incident-response mutators (revoke_lease, lease_revoke_prefix, operator_step_down, operator_seal) need sys/* capabilities, so a read-only token will see those denied.","TLS to an https:// `VAULT_ADDR` uses the system CA bundle; set VAULT_CACERT for a private CA, or VAULT_SKIP_VERIFY=1 only in non-production."],"verify":"vault.status"},"actions":[{"id":"vault.cubbyhole_list","title":"vault list cubbyhole","summary":"List the runner token's own cubbyhole (each token sees only its own).","description":"List the runner token's own cubbyhole (each token sees only its own).","kind":"exec","risk":"low","side_effects":["One cubbyhole/ request.","Read-only — values not returned, only keys."],"args":[],"examples":[{"title":"Cubbyhole keys","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","cubbyhole/"]}},{"id":"vault.lease_revoke_prefix","title":"vault lease revoke -prefix <prefix>","summary":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","description":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","kind":"exec","risk":"high","side_effects":["Every lease under the prefix revoked.","Dynamic credentials (DB users, AWS keys, etc.) revoked at the upstream.","Affected clients see auth failures until they request new credentials."],"args":[{"name":"prefix","type":"string","required":true,"description":"Lease prefix.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Revoke all DB credentials","args":{"prefix":"database/creds/"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","-prefix","{{ args.prefix }}"]}},{"id":"vault.leases_count","title":"vault list sys/leases/lookup/<prefix>","summary":"Count of active leases under one mount prefix.","description":"Count of active leases under one mount prefix.","kind":"exec","risk":"low","side_effects":["One sys/leases/lookup request.","Read-only."],"args":[{"name":"prefix","type":"string","required":true,"description":"Mount/role prefix (no leading slash).","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Leases under aws/creds/readonly","args":{"prefix":"aws/creds/readonly"}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","sys/leases/lookup/{{ args.prefix }}"]}},{"id":"vault.list_audit","title":"vault audit list","summary":"List enabled audit devices.","description":"List enabled audit devices.","kind":"exec","risk":"low","side_effects":["One sys/audit request.","Read-only."],"args":[],"examples":[{"title":"Audit devices","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["audit","list","-format=json"]}},{"id":"vault.list_auth","title":"vault auth list","summary":"List all auth method mounts.","description":"List all auth method mounts.","kind":"exec","risk":"low","side_effects":["One sys/auth request.","Read-only."],"args":[],"examples":[{"title":"Auth methods","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["auth","list","-format=json"]}},{"id":"vault.list_mounts","title":"vault secrets list","summary":"List all secret engine mount points.","description":"List all secret engine mount points.","kind":"exec","risk":"low","side_effects":["One sys/mounts request.","Read-only."],"args":[],"examples":[{"title":"Secret mounts","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["secrets","list","-format=json"]}},{"id":"vault.list_policies","title":"vault policy list","summary":"List all policy names.","description":"List all policy names.","kind":"exec","risk":"low","side_effects":["One sys/policy request.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","list","-format=json"]}},{"id":"vault.operator_seal","title":"vault operator seal","summary":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","description":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","kind":"exec","risk":"critical","side_effects":["Vault sealed; all secret operations fail.","Active leases continue to be enforced by downstreams but cannot be renewed.","Recovery needs unseal keys (auto-unseal still requires KMS/cloud HSM)."],"args":[],"examples":[{"title":"Emergency seal","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","seal"]}},{"id":"vault.operator_step_down","title":"vault operator step-down","summary":"Force the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","description":"Force the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","kind":"exec","risk":"critical","side_effects":["Brief unavailability during leader election (~1-5 seconds).","In-flight requests on the stepping-down node fail."],"args":[],"examples":[{"title":"Force failover","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","step-down"]}},{"id":"vault.read_policy","title":"vault policy read <name>","summary":"Read the HCL document for one policy.","description":"Read the HCL document for one policy.","kind":"exec","risk":"low","side_effects":["One sys/policy/<name> request.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Policy name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Read 'default' policy","args":{"name":"default"}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","read","{{ args.name }}"]}},{"id":"vault.revoke_lease","title":"vault lease revoke <id>","summary":"Revoke one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","description":"Revoke one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","kind":"exec","risk":"high","side_effects":["Lease is revoked; underlying credential disabled.","In-flight requests using the credential will fail."],"args":[{"name":"lease_id","type":"string","required":true,"description":"Full lease ID.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,511}$"}}],"examples":[{"title":"Revoke one","args":{"lease_id":"aws/creds/readonly/abc123"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","{{ args.lease_id }}"]}},{"id":"vault.seal_status","title":"vault status (seal fields)","summary":"Show sealed/unsealed state + threshold + progress.","description":"Show sealed/unsealed state + threshold + progress.","kind":"exec","risk":"low","side_effects":["One sys/seal-status request.","Read-only."],"args":[],"examples":[{"title":"Seal status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.status","title":"vault status","summary":"Show top-level Vault status: sealed, version, HA mode, active node.","description":"Show top-level Vault status: sealed, version, HA mode, active node.","kind":"exec","risk":"low","side_effects":["One sys/health request.","Read-only."],"args":[],"examples":[{"title":"Vault status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.token_lookup_self","title":"vault token lookup","summary":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","description":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","kind":"exec","risk":"low","side_effects":["One auth/token/lookup-self request.","Read-only; the token value (data.id) returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self lookup","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["token","lookup","-format=json"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:53bbdee234200ab19201c961471ec8b2a0b14161745248f35a872376dd9dbab0","tarball_url":"https://registry.emisar.dev/v1/packs/vault/0.1.9/53bbdee234200ab19201c961471ec8b2a0b14161745248f35a872376dd9dbab0/pack.tar.gz","actions":[{"id":"vault.cubbyhole_list","title":"vault list cubbyhole","summary":"List the runner token's own cubbyhole (each token sees only its own).","description":"List the runner token's own cubbyhole (each token sees only its own).","kind":"exec","risk":"low","side_effects":["One cubbyhole/ request.","Read-only — values not returned, only keys."],"args":[],"examples":[{"title":"Cubbyhole keys","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","cubbyhole/"]}},{"id":"vault.lease_revoke_prefix","title":"vault lease revoke -prefix <prefix>","summary":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","description":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","kind":"exec","risk":"high","side_effects":["Every lease under the prefix revoked.","Dynamic credentials (DB users, AWS keys, etc.) revoked at the upstream.","Affected clients see auth failures until they request new credentials."],"args":[{"name":"prefix","type":"string","required":true,"description":"Lease prefix.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Revoke all DB credentials","args":{"prefix":"database/creds/"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","-prefix","{{ args.prefix }}"]}},{"id":"vault.leases_count","title":"vault list sys/leases/lookup/<prefix>","summary":"Count of active leases under one mount prefix.","description":"Count of active leases under one mount prefix.","kind":"exec","risk":"low","side_effects":["One sys/leases/lookup request.","Read-only."],"args":[{"name":"prefix","type":"string","required":true,"description":"Mount/role prefix (no leading slash).","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Leases under aws/creds/readonly","args":{"prefix":"aws/creds/readonly"}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","sys/leases/lookup/{{ args.prefix }}"]}},{"id":"vault.list_audit","title":"vault audit list","summary":"List enabled audit devices.","description":"List enabled audit devices.","kind":"exec","risk":"low","side_effects":["One sys/audit request.","Read-only."],"args":[],"examples":[{"title":"Audit devices","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["audit","list","-format=json"]}},{"id":"vault.list_auth","title":"vault auth list","summary":"List all auth method mounts.","description":"List all auth method mounts.","kind":"exec","risk":"low","side_effects":["One sys/auth request.","Read-only."],"args":[],"examples":[{"title":"Auth methods","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["auth","list","-format=json"]}},{"id":"vault.list_mounts","title":"vault secrets list","summary":"List all secret engine mount points.","description":"List all secret engine mount points.","kind":"exec","risk":"low","side_effects":["One sys/mounts request.","Read-only."],"args":[],"examples":[{"title":"Secret mounts","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["secrets","list","-format=json"]}},{"id":"vault.list_policies","title":"vault policy list","summary":"List all policy names.","description":"List all policy names.","kind":"exec","risk":"low","side_effects":["One sys/policy request.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","list","-format=json"]}},{"id":"vault.operator_seal","title":"vault operator seal","summary":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","description":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","kind":"exec","risk":"critical","side_effects":["Vault sealed; all secret operations fail.","Active leases continue to be enforced by downstreams but cannot be renewed.","Recovery needs unseal keys (auto-unseal still requires KMS/cloud HSM)."],"args":[],"examples":[{"title":"Emergency seal","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","seal"]}},{"id":"vault.operator_step_down","title":"vault operator step-down","summary":"Force the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","description":"Force the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","kind":"exec","risk":"critical","side_effects":["Brief unavailability during leader election (~1-5 seconds).","In-flight requests on the stepping-down node fail."],"args":[],"examples":[{"title":"Force failover","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","step-down"]}},{"id":"vault.read_policy","title":"vault policy read <name>","summary":"Read the HCL document for one policy.","description":"Read the HCL document for one policy.","kind":"exec","risk":"low","side_effects":["One sys/policy/<name> request.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Policy name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Read 'default' policy","args":{"name":"default"}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","read","{{ args.name }}"]}},{"id":"vault.revoke_lease","title":"vault lease revoke <id>","summary":"Revoke one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","description":"Revoke one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","kind":"exec","risk":"high","side_effects":["Lease is revoked; underlying credential disabled.","In-flight requests using the credential will fail."],"args":[{"name":"lease_id","type":"string","required":true,"description":"Full lease ID.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,511}$"}}],"examples":[{"title":"Revoke one","args":{"lease_id":"aws/creds/readonly/abc123"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","{{ args.lease_id }}"]}},{"id":"vault.seal_status","title":"vault status (seal fields)","summary":"Show sealed/unsealed state + threshold + progress.","description":"Show sealed/unsealed state + threshold + progress.","kind":"exec","risk":"low","side_effects":["One sys/seal-status request.","Read-only."],"args":[],"examples":[{"title":"Seal status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.status","title":"vault status","summary":"Show top-level Vault status: sealed, version, HA mode, active node.","description":"Show top-level Vault status: sealed, version, HA mode, active node.","kind":"exec","risk":"low","side_effects":["One sys/health request.","Read-only."],"args":[],"examples":[{"title":"Vault status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.token_lookup_self","title":"vault token lookup","summary":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","description":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","kind":"exec","risk":"low","side_effects":["One auth/token/lookup-self request.","Read-only; the token value (data.id) returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self lookup","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["token","lookup","-format=json"]}}]},{"version":"0.1.8","content_hash":"sha256:81805eb9153e64a5cd8a447460a71ffc83d27e521e2039b511e34842b902bc5e","tarball_url":"https://registry.emisar.dev/v1/packs/vault/0.1.8/81805eb9153e64a5cd8a447460a71ffc83d27e521e2039b511e34842b902bc5e/pack.tar.gz","actions":[{"id":"vault.cubbyhole_list","title":"vault list cubbyhole","summary":"Lists the runner token's own cubbyhole (each token sees only its own).","description":"Lists the runner token's own cubbyhole (each token sees only its own).","kind":"exec","risk":"low","side_effects":["One cubbyhole/ request.","Read-only — values not returned, only keys."],"args":[],"examples":[{"title":"Cubbyhole keys","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","cubbyhole/"]}},{"id":"vault.lease_revoke_prefix","title":"vault lease revoke -prefix <prefix>","summary":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","description":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","kind":"exec","risk":"high","side_effects":["Every lease under the prefix revoked.","Dynamic credentials (DB users, AWS keys, etc.) revoked at the upstream.","Affected clients see auth failures until they request new credentials."],"args":[{"name":"prefix","type":"string","required":true,"description":"Lease prefix.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Revoke all DB credentials","args":{"prefix":"database/creds/"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","-prefix","{{ args.prefix }}"]}},{"id":"vault.leases_count","title":"vault list sys/leases/lookup/<prefix>","summary":"Count of active leases under one mount prefix.","description":"Count of active leases under one mount prefix.","kind":"exec","risk":"low","side_effects":["One sys/leases/lookup request.","Read-only."],"args":[{"name":"prefix","type":"string","required":true,"description":"Mount/role prefix (no leading slash).","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Leases under aws/creds/readonly","args":{"prefix":"aws/creds/readonly"}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","sys/leases/lookup/{{ args.prefix }}"]}},{"id":"vault.list_audit","title":"vault audit list","summary":"List enabled audit devices.","description":"List enabled audit devices.","kind":"exec","risk":"low","side_effects":["One sys/audit request.","Read-only."],"args":[],"examples":[{"title":"Audit devices","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["audit","list","-format=json"]}},{"id":"vault.list_auth","title":"vault auth list","summary":"List all auth method mounts.","description":"List all auth method mounts.","kind":"exec","risk":"low","side_effects":["One sys/auth request.","Read-only."],"args":[],"examples":[{"title":"Auth methods","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["auth","list","-format=json"]}},{"id":"vault.list_mounts","title":"vault secrets list","summary":"List all secret engine mount points.","description":"List all secret engine mount points.","kind":"exec","risk":"low","side_effects":["One sys/mounts request.","Read-only."],"args":[],"examples":[{"title":"Secret mounts","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["secrets","list","-format=json"]}},{"id":"vault.list_policies","title":"vault policy list","summary":"List all policy names.","description":"List all policy names.","kind":"exec","risk":"low","side_effects":["One sys/policy request.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","list","-format=json"]}},{"id":"vault.operator_seal","title":"vault operator seal","summary":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","description":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","kind":"exec","risk":"critical","side_effects":["Vault sealed; all secret operations fail.","Active leases continue to be enforced by downstreams but cannot be renewed.","Recovery needs unseal keys (auto-unseal still requires KMS/cloud HSM)."],"args":[],"examples":[{"title":"Emergency seal","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","seal"]}},{"id":"vault.operator_step_down","title":"vault operator step-down","summary":"Forces the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","description":"Forces the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","kind":"exec","risk":"critical","side_effects":["Brief unavailability during leader election (~1-5 seconds).","In-flight requests on the stepping-down node fail."],"args":[],"examples":[{"title":"Force failover","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","step-down"]}},{"id":"vault.read_policy","title":"vault policy read <name>","summary":"Read the HCL document for one policy.","description":"Read the HCL document for one policy.","kind":"exec","risk":"low","side_effects":["One sys/policy/<name> request.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Policy name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Read 'default' policy","args":{"name":"default"}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","read","{{ args.name }}"]}},{"id":"vault.revoke_lease","title":"vault lease revoke <id>","summary":"Revokes one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","description":"Revokes one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","kind":"exec","risk":"high","side_effects":["Lease is revoked; underlying credential disabled.","In-flight requests using the credential will fail."],"args":[{"name":"lease_id","type":"string","required":true,"description":"Full lease ID.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,511}$"}}],"examples":[{"title":"Revoke one","args":{"lease_id":"aws/creds/readonly/abc123"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","{{ args.lease_id }}"]}},{"id":"vault.seal_status","title":"vault status (seal fields)","summary":"Show sealed/unsealed state + threshold + progress.","description":"Show sealed/unsealed state + threshold + progress.","kind":"exec","risk":"low","side_effects":["One sys/seal-status request.","Read-only."],"args":[],"examples":[{"title":"Seal status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.status","title":"vault status","summary":"Show top-level Vault status: sealed, version, HA mode, active node.","description":"Show top-level Vault status: sealed, version, HA mode, active node.","kind":"exec","risk":"low","side_effects":["One sys/health request.","Read-only."],"args":[],"examples":[{"title":"Vault status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.token_lookup_self","title":"vault token lookup","summary":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","description":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","kind":"exec","risk":"low","side_effects":["One auth/token/lookup-self request.","Read-only; the token value (data.id) returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self lookup","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["token","lookup","-format=json"]}}]},{"version":"0.1.7","content_hash":"sha256:f3cfd948577e0870cc2a18d9690473a991320bef43b41393f1ad99cfe915b018","tarball_url":"https://registry.emisar.dev/v1/packs/vault/0.1.7/f3cfd948577e0870cc2a18d9690473a991320bef43b41393f1ad99cfe915b018/pack.tar.gz","actions":[{"id":"vault.cubbyhole_list","title":"vault list cubbyhole","summary":"Lists the runner token's own cubbyhole (each token sees only its own).","description":"Lists the runner token's own cubbyhole (each token sees only its own).","kind":"exec","risk":"low","side_effects":["One cubbyhole/ request.","Read-only — values not returned, only keys."],"args":[],"examples":[{"title":"Cubbyhole keys","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","cubbyhole/"]}},{"id":"vault.lease_revoke_prefix","title":"vault lease revoke -prefix <prefix>","summary":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","description":"Revoke every lease under a path prefix. Use after a compromise to invalidate every dynamic credential for one engine. Irreversible for issued credentials — affected services must re-authenticate.","kind":"exec","risk":"high","side_effects":["Every lease under the prefix revoked.","Dynamic credentials (DB users, AWS keys, etc.) revoked at the upstream.","Affected clients see auth failures until they request new credentials."],"args":[{"name":"prefix","type":"string","required":true,"description":"Lease prefix.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Revoke all DB credentials","args":{"prefix":"database/creds/"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","-prefix","{{ args.prefix }}"]}},{"id":"vault.leases_count","title":"vault list sys/leases/lookup/<prefix>","summary":"Count of active leases under one mount prefix.","description":"Count of active leases under one mount prefix.","kind":"exec","risk":"low","side_effects":["One sys/leases/lookup request.","Read-only."],"args":[{"name":"prefix","type":"string","required":true,"description":"Mount/role prefix (no leading slash).","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,255}$"}}],"examples":[{"title":"Leases under aws/creds/readonly","args":{"prefix":"aws/creds/readonly"}}],"search_terms":[],"command":{"binary":"vault","argv":["list","-format=json","sys/leases/lookup/{{ args.prefix }}"]}},{"id":"vault.list_audit","title":"vault audit list","summary":"List enabled audit devices.","description":"List enabled audit devices.","kind":"exec","risk":"low","side_effects":["One sys/audit request.","Read-only."],"args":[],"examples":[{"title":"Audit devices","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["audit","list","-format=json"]}},{"id":"vault.list_auth","title":"vault auth list","summary":"List all auth method mounts.","description":"List all auth method mounts.","kind":"exec","risk":"low","side_effects":["One sys/auth request.","Read-only."],"args":[],"examples":[{"title":"Auth methods","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["auth","list","-format=json"]}},{"id":"vault.list_mounts","title":"vault secrets list","summary":"List all secret engine mount points.","description":"List all secret engine mount points.","kind":"exec","risk":"low","side_effects":["One sys/mounts request.","Read-only."],"args":[],"examples":[{"title":"Secret mounts","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["secrets","list","-format=json"]}},{"id":"vault.list_policies","title":"vault policy list","summary":"List all policy names.","description":"List all policy names.","kind":"exec","risk":"low","side_effects":["One sys/policy request.","Read-only."],"args":[],"examples":[{"title":"Policies","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","list","-format=json"]}},{"id":"vault.operator_seal","title":"vault operator seal","summary":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","description":"Seal Vault. ALL clients lose access to secrets immediately; ongoing requests fail. Recovery requires unseal keys from a quorum of shareholders. Use only for compromised-cluster containment.","kind":"exec","risk":"critical","side_effects":["Vault sealed; all secret operations fail.","Active leases continue to be enforced by downstreams but cannot be renewed.","Recovery needs unseal keys (auto-unseal still requires KMS/cloud HSM)."],"args":[],"examples":[{"title":"Emergency seal","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","seal"]}},{"id":"vault.operator_step_down","title":"vault operator step-down","summary":"Forces the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","description":"Forces the active node to step down. A standby will take over within seconds. Use this to force a failover or to drain a node before maintenance.","kind":"exec","risk":"critical","side_effects":["Brief unavailability during leader election (~1-5 seconds).","In-flight requests on the stepping-down node fail."],"args":[],"examples":[{"title":"Force failover","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","step-down"]}},{"id":"vault.read_policy","title":"vault policy read <name>","summary":"Read the HCL document for one policy.","description":"Read the HCL document for one policy.","kind":"exec","risk":"low","side_effects":["One sys/policy/<name> request.","Read-only."],"args":[{"name":"name","type":"string","required":true,"description":"Policy name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,127}$"}}],"examples":[{"title":"Read 'default' policy","args":{"name":"default"}}],"search_terms":[],"command":{"binary":"vault","argv":["policy","read","{{ args.name }}"]}},{"id":"vault.revoke_lease","title":"vault lease revoke <id>","summary":"Revokes one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","description":"Revokes one lease — the credential becomes invalid immediately. Anyone using it gets a 403 from the downstream system.","kind":"exec","risk":"high","side_effects":["Lease is revoked; underlying credential disabled.","In-flight requests using the credential will fail."],"args":[{"name":"lease_id","type":"string","required":true,"description":"Full lease ID.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,511}$"}}],"examples":[{"title":"Revoke one","args":{"lease_id":"aws/creds/readonly/abc123"}}],"search_terms":[],"command":{"binary":"vault","argv":["lease","revoke","{{ args.lease_id }}"]}},{"id":"vault.seal_status","title":"vault operator seal-status","summary":"Show sealed/unsealed state + threshold + progress.","description":"Show sealed/unsealed state + threshold + progress.","kind":"exec","risk":"low","side_effects":["One sys/seal-status request.","Read-only."],"args":[],"examples":[{"title":"Seal status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["operator","seal-status","-format=json"]}},{"id":"vault.status","title":"vault status","summary":"Show top-level Vault status: sealed, version, HA mode, active node.","description":"Show top-level Vault status: sealed, version, HA mode, active node.","kind":"exec","risk":"low","side_effects":["One sys/health request.","Read-only."],"args":[],"examples":[{"title":"Vault status","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["status","-format=json"]}},{"id":"vault.token_lookup_self","title":"vault token lookup","summary":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","description":"Show metadata on the current token (the runner's) — accessor, policies, ttl. Useful to debug policy denials. The token itself (data.id) is redacted from the output.","kind":"exec","risk":"low","side_effects":["One auth/token/lookup-self request.","Read-only; the token value (data.id) returned by the API is redacted before output."],"args":[],"examples":[{"title":"Self lookup","args":{}}],"search_terms":[],"command":{"binary":"vault","argv":["token","lookup","-format=json"]}}]}],"retired_below":"0.1.7"},{"id":"vector","name":"Vector observability pipeline","version":"0.1.14","description":"Read-only ops for a Vector (vector.dev) pipeline running on the runner host: version + compiled-component inventory, offline config validation, the configured topology as Graphviz DOT, a bounded live event tap, plus health and per-component throughput reads over the local API. CLI subcommands talk to the local binary; the API reads hit 127.0.0.1:8686.","vendor":"emisar","homepage":"https://emisar.dev/packs/vector","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/vector","content_hash":"sha256:cf355094828e38eeab54bdee4d017d136d5db2f87786b1d437790b9dd6d62aa1","tarball_url":"https://registry.emisar.dev/v1/packs/vector/0.1.14/cf355094828e38eeab54bdee4d017d136d5db2f87786b1d437790b9dd6d62aa1/pack.tar.gz","requires":{"os":["linux"],"binaries":["vector","curl"]},"detect":{"binaries":[],"processes":["vector"],"ports":[8686]},"setup":{"summary":"Drives the local Vector instance on the runner host: the CLI actions invoke the `vector` binary directly, and the health / metrics reads call Vector's HTTP API at `$VECTOR_API` (default 127.0.0.1:8686). No credentials — the API is unauthenticated and binds loopback only.","env":[{"name":"VECTOR_API","description":"Vector GraphQL/health API base URL; requires api.enabled=true in the Vector config.","default":"http://127.0.0.1:8686"}],"notes":["`VECTOR_API` only reaches an action when the runner allowlists it in `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default. Unset, it falls back to http://127.0.0.1:8686, so a Vector API bound elsewhere silently reads the local one instead.","The HTTP API is unauthenticated and binds 127.0.0.1:8686 only when `api.enabled = true` in the Vector config. The CLI actions (version, list, validate, graph, tap) do not need it — they talk to the local binary and work whether or not the API is on.","VERSION CAVEAT: Vector's observability API was GraphQL (`/graphql`, `/playground`) through v0.54, then migrated to gRPC in v0.55 (April 2026), which REMOVED both. So the CLI subcommands work on ANY version, plain `GET /health` works on ANY version, but the raw GraphQL component_metrics action only works on Vector <= 0.54 (it 404s on >= 0.55). Run `vector.version` first; on >= 0.55 use gRPC tooling for component metrics instead.","Every action is read-only — none start, stop, reload, or reconfigure Vector. `tap` adds slight overhead on the running instance while sampling, then auto-exits."],"host_access":[{"actions":["vector.validate","vector.graph"],"requirement":"Read Vector's protected configuration even when deployment replaces restrictive files.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-vector-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root","sudo test -r /etc/vector/vector.yaml"],"impact":"Every Emisar action on this runner executes as root and can read every Vector config, including sink credentials embedded directly in those files."}]}],"verify":"vector.health"},"actions":[{"id":"vector.component_metrics","title":"POST /graphql (component metrics)","summary":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","description":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only GraphQL POST (a query, not a mutation) to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Per-component event + byte totals (Vector <= 0.54)","args":{}}],"search_terms":["backpressure"],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https -X POST \"${VECTOR_API:-http://127.0.0.1:8686}/graphql\" -H 'Content-Type: application/json' --data '{\"query\":\"query { sources { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } transforms { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } sinks { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } sentBytesTotal { sentBytesTotal } } } } } }\"}'"]}},{"id":"vector.graph","title":"vector graph","summary":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","description":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the Vector config and emits its topology as DOT.","Read-only."],"args":[],"examples":[{"title":"Topology as Graphviz DOT","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["graph"]}},{"id":"vector.health","title":"GET /health","summary":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","description":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only HTTP GET to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Is Vector serving?","args":{}}],"search_terms":["logs stopped flowing","log pipeline","not shipping logs"],"command":{"binary":"/bin/sh","argv":["-c","curl -q -fsS --globoff --proto =http,https \"${VECTOR_API:-http://127.0.0.1:8686}/health\""]}},{"id":"vector.list","title":"vector list --format json","summary":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","description":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary's component list.","Read-only."],"args":[],"examples":[{"title":"Components compiled into the binary","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["list","--format","json"]}},{"id":"vector.tap","title":"vector tap --outputs-of","summary":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","description":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","kind":"exec","risk":"medium","side_effects":["Subscribes to a component's output stream on the local Vector instance.","Slight runtime overhead while sampling; auto-exits after duration_ms.","Read-only — observes events, never modifies the pipeline."],"args":[{"name":"component","type":"string","required":true,"description":"Component ID (or glob) whose outputs to tap, e.g. parse_json or \"transform_*\".","validation":{"pattern":"^[A-Za-z0-9._*][A-Za-z0-9._*-]{0,127}$"}},{"name":"duration_ms","type":"integer","required":false,"default":2000,"description":"How long to sample before auto-exiting, in milliseconds. This is what bounds the run.","validation":{"min":100,"max":10000}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Max events per sampling interval (per-interval cap, NOT a total — duration_ms bounds the run).","validation":{"min":1,"max":1000}}],"examples":[{"title":"Sample one transform's output for 2s","args":{"component":"parse_json"}},{"title":"Sample a sink's input briefly with a small per-interval cap","args":{"component":"datadog_logs","duration_ms":1000,"limit":20}}],"search_terms":["logs stopped flowing","log pipeline"],"command":{"binary":"vector","argv":["tap","--duration-ms","{{ args.duration_ms }}","--limit","{{ args.limit }}","--quiet","--format","json","--outputs-of","{{ args.component }}"]}},{"id":"vector.validate","title":"vector validate --no-environment","summary":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","description":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads and parses a Vector config file on the runner host.","Read-only — no network healthchecks (--no-environment), no reload."],"args":[{"name":"config_path","type":"string","required":false,"default":"/etc/vector/vector.yaml","description":"Path to the Vector config file to validate.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/vector/"]}}],"examples":[{"title":"Validate the default config","args":{}},{"title":"Validate a specific config file","args":{"config_path":"/etc/vector/pipelines/api.yaml"}}],"search_terms":[],"command":{"binary":"vector","argv":["validate","--no-environment","{{ args.config_path }}"]}},{"id":"vector.version","title":"vector --version","summary":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","description":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary version.","Read-only."],"args":[],"examples":[{"title":"Show version (and pick GraphQL vs gRPC)","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["--version"]}}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:20f17da052c3637f0c52f8a660b6057cc0d1f2314df6285cd8dd04c0bb0e6917","tarball_url":"https://registry.emisar.dev/v1/packs/vector/0.1.10/20f17da052c3637f0c52f8a660b6057cc0d1f2314df6285cd8dd04c0bb0e6917/pack.tar.gz","actions":[{"id":"vector.component_metrics","title":"POST /graphql (component metrics)","summary":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","description":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only GraphQL POST (a query, not a mutation) to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Per-component event + byte totals (Vector <= 0.54)","args":{}}],"search_terms":["backpressure"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${VECTOR_API:-http://127.0.0.1:8686}/graphql\" -H 'Content-Type: application/json' --data '{\"query\":\"query { sources { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } transforms { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } sinks { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } sentBytesTotal { sentBytesTotal } } } } } }\"}'"]}},{"id":"vector.graph","title":"vector graph","summary":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","description":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the Vector config and emits its topology as DOT.","Read-only."],"args":[],"examples":[{"title":"Topology as Graphviz DOT","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["graph"]}},{"id":"vector.health","title":"GET /health","summary":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","description":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only HTTP GET to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Is Vector serving?","args":{}}],"search_terms":["logs stopped flowing","log pipeline","not shipping logs"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${VECTOR_API:-http://127.0.0.1:8686}/health\""]}},{"id":"vector.list","title":"vector list --format json","summary":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","description":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary's component list.","Read-only."],"args":[],"examples":[{"title":"Components compiled into the binary","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["list","--format","json"]}},{"id":"vector.tap","title":"vector tap --outputs-of","summary":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","description":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","kind":"exec","risk":"low","side_effects":["Subscribes to a component's output stream on the local Vector instance.","Slight runtime overhead while sampling; auto-exits after duration_ms.","Read-only — observes events, never modifies the pipeline."],"args":[{"name":"component","type":"string","required":true,"description":"Component ID (or glob) whose outputs to tap, e.g. parse_json or \"transform_*\".","validation":{"pattern":"^[A-Za-z0-9._*][A-Za-z0-9._*-]{0,127}$"}},{"name":"duration_ms","type":"integer","required":false,"default":2000,"description":"How long to sample before auto-exiting, in milliseconds. This is what bounds the run.","validation":{"min":100,"max":10000}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Max events per sampling interval (per-interval cap, NOT a total — duration_ms bounds the run).","validation":{"min":1,"max":1000}}],"examples":[{"title":"Sample one transform's output for 2s","args":{"component":"parse_json"}},{"title":"Sample a sink's input briefly with a small per-interval cap","args":{"component":"datadog_logs","duration_ms":1000,"limit":20}}],"search_terms":["logs stopped flowing","log pipeline"],"command":{"binary":"vector","argv":["tap","--duration-ms","{{ args.duration_ms }}","--limit","{{ args.limit }}","--quiet","--format","json","--outputs-of","{{ args.component }}"]}},{"id":"vector.validate","title":"vector validate --no-environment","summary":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","description":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads and parses a Vector config file on the runner host.","Read-only — no network healthchecks (--no-environment), no reload."],"args":[{"name":"config_path","type":"string","required":false,"default":"/etc/vector/vector.yaml","description":"Path to the Vector config file to validate.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/vector/"]}}],"examples":[{"title":"Validate the default config","args":{}},{"title":"Validate a specific config file","args":{"config_path":"/etc/vector/pipelines/api.yaml"}}],"search_terms":[],"command":{"binary":"vector","argv":["validate","--no-environment","{{ args.config_path }}"]}},{"id":"vector.version","title":"vector --version","summary":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","description":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary version.","Read-only."],"args":[],"examples":[{"title":"Show version (and pick GraphQL vs gRPC)","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["--version"]}}]},{"version":"0.1.8","content_hash":"sha256:0f087e7b330db8d4e0ff4ce11de0036a3aa53864c0b0b6b0055d2d7d6cf9f662","tarball_url":"https://registry.emisar.dev/v1/packs/vector/0.1.8/0f087e7b330db8d4e0ff4ce11de0036a3aa53864c0b0b6b0055d2d7d6cf9f662/pack.tar.gz","actions":[{"id":"vector.component_metrics","title":"POST /graphql (component metrics)","summary":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","description":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only GraphQL POST (a query, not a mutation) to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Per-component event + byte totals (Vector <= 0.54)","args":{}}],"search_terms":["backpressure"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${VECTOR_API:-http://127.0.0.1:8686}/graphql\" -H 'Content-Type: application/json' --data '{\"query\":\"query { sources { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } transforms { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } sinks { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } sentBytesTotal { sentBytesTotal } } } } } }\"}'"]}},{"id":"vector.graph","title":"vector graph","summary":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","description":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the Vector config and emits its topology as DOT.","Read-only."],"args":[],"examples":[{"title":"Topology as Graphviz DOT","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["graph"]}},{"id":"vector.health","title":"GET /health","summary":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","description":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only HTTP GET to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Is Vector serving?","args":{}}],"search_terms":["logs stopped flowing","log pipeline","not shipping logs"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${VECTOR_API:-http://127.0.0.1:8686}/health\""]}},{"id":"vector.list","title":"vector list --format json","summary":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","description":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary's component list.","Read-only."],"args":[],"examples":[{"title":"Components compiled into the binary","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["list","--format","json"]}},{"id":"vector.tap","title":"vector tap --outputs-of","summary":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","description":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","kind":"exec","risk":"low","side_effects":["Subscribes to a component's output stream on the local Vector instance.","Slight runtime overhead while sampling; auto-exits after duration_ms.","Read-only — observes events, never modifies the pipeline."],"args":[{"name":"component","type":"string","required":true,"description":"Component ID (or glob) whose outputs to tap, e.g. parse_json or \"transform_*\".","validation":{"pattern":"^[A-Za-z0-9._*][A-Za-z0-9._*-]{0,127}$"}},{"name":"duration_ms","type":"integer","required":false,"default":2000,"description":"How long to sample before auto-exiting, in milliseconds. This is what bounds the run.","validation":{"min":100,"max":10000}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Max events per sampling interval (per-interval cap, NOT a total — duration_ms bounds the run).","validation":{"min":1,"max":1000}}],"examples":[{"title":"Sample one transform's output for 2s","args":{"component":"parse_json"}},{"title":"Sample a sink's input briefly with a small per-interval cap","args":{"component":"datadog_logs","duration_ms":1000,"limit":20}}],"search_terms":["logs stopped flowing","log pipeline"],"command":{"binary":"vector","argv":["tap","--duration-ms","{{ args.duration_ms }}","--limit","{{ args.limit }}","--quiet","--format","json","--outputs-of","{{ args.component }}"]}},{"id":"vector.validate","title":"vector validate --no-environment","summary":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","description":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads and parses a Vector config file on the runner host.","Read-only — no network healthchecks (--no-environment), no reload."],"args":[{"name":"config_path","type":"string","required":false,"default":"/etc/vector/vector.yaml","description":"Path to the Vector config file to validate.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/vector/"]}}],"examples":[{"title":"Validate the default config","args":{}},{"title":"Validate a specific config file","args":{"config_path":"/etc/vector/pipelines/api.yaml"}}],"search_terms":[],"command":{"binary":"vector","argv":["validate","--no-environment","{{ args.config_path }}"]}},{"id":"vector.version","title":"vector --version","summary":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","description":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary version.","Read-only."],"args":[],"examples":[{"title":"Show version (and pick GraphQL vs gRPC)","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["--version"]}}]},{"version":"0.1.7","content_hash":"sha256:de374d21fd556dbf836e04cd454ed1fd0582faff17f8029d10815aa5577710b7","tarball_url":"https://registry.emisar.dev/v1/packs/vector/0.1.7/de374d21fd556dbf836e04cd454ed1fd0582faff17f8029d10815aa5577710b7/pack.tar.gz","actions":[{"id":"vector.component_metrics","title":"POST /graphql (component metrics)","summary":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","description":"Show per-component throughput from the Vector GraphQL API: received and sent event totals for every source, transform, and sink, plus sent-bytes for sinks. GraphQL API — Vector <= 0.54 ONLY. On Vector >= 0.55 (gRPC migration, April 2026) the /graphql endpoint was REMOVED and this returns 404; run vector.version first and, if >= 0.55, use gRPC tooling instead. Requires api.enabled=true; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only GraphQL POST (a query, not a mutation) to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Per-component event + byte totals (Vector <= 0.54)","args":{}}],"search_terms":["backpressure"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https -X POST \"${VECTOR_API:-http://127.0.0.1:8686}/graphql\" -H 'Content-Type: application/json' --data '{\"query\":\"query { sources { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } transforms { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } } } } } sinks { edges { node { componentId metrics { receivedEventsTotal { receivedEventsTotal } sentEventsTotal { sentEventsTotal } sentBytesTotal { sentBytesTotal } } } } } }\"}'"]}},{"id":"vector.graph","title":"vector graph","summary":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","description":"Render the configured Vector topology as a Graphviz DOT graph — the source -> transform -> sink wiring read from the config file. Offline: reads the config, emits DOT, connects to nothing. Pipe the output to `dot` to draw it. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the Vector config and emits its topology as DOT.","Read-only."],"args":[],"examples":[{"title":"Topology as Graphviz DOT","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["graph"]}},{"id":"vector.health","title":"GET /health","summary":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","description":"Check liveness of the local Vector API. Returns {\"ok\":true} (HTTP 200) when serving, or {\"ok\":false} (HTTP 503) while draining/shutting down. Works on ANY Vector version — this endpoint survived the v0.55 gRPC migration. Requires api.enabled=true in the Vector config; binds 127.0.0.1:8686.","kind":"exec","risk":"low","side_effects":["One read-only HTTP GET to the local Vector API.","Read-only."],"args":[],"examples":[{"title":"Is Vector serving?","args":{}}],"search_terms":["logs stopped flowing","log pipeline","not shipping logs"],"command":{"binary":"/bin/sh","argv":["-c","curl -fsS --globoff --proto =http,https \"${VECTOR_API:-http://127.0.0.1:8686}/health\""]}},{"id":"vector.list","title":"vector list --format json","summary":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","description":"List the sources, transforms, and sinks compiled into this Vector binary, as JSON. This is the static component catalog of the build — not the running topology (use vector.graph for what is actually configured). Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary's component list.","Read-only."],"args":[],"examples":[{"title":"Components compiled into the binary","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["list","--format","json"]}},{"id":"vector.tap","title":"vector tap --outputs-of","summary":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","description":"Sample live events flowing OUT of a named component for a bounded window, as JSON, then auto-exit. The run terminates after duration_ms — NOT on --limit alone, which caps events PER sampling interval, not total, so without a duration a tap can run indefinitely. Adds slight overhead on the running Vector instance while sampling. Connects to the local API (tap is API-backed); component is matched against configured component IDs and supports glob patterns.","kind":"exec","risk":"low","side_effects":["Subscribes to a component's output stream on the local Vector instance.","Slight runtime overhead while sampling; auto-exits after duration_ms.","Read-only — observes events, never modifies the pipeline."],"args":[{"name":"component","type":"string","required":true,"description":"Component ID (or glob) whose outputs to tap, e.g. parse_json or \"transform_*\".","validation":{"pattern":"^[A-Za-z0-9._*][A-Za-z0-9._*-]{0,127}$"}},{"name":"duration_ms","type":"integer","required":false,"default":2000,"description":"How long to sample before auto-exiting, in milliseconds. This is what bounds the run.","validation":{"min":100,"max":10000}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Max events per sampling interval (per-interval cap, NOT a total — duration_ms bounds the run).","validation":{"min":1,"max":1000}}],"examples":[{"title":"Sample one transform's output for 2s","args":{"component":"parse_json"}},{"title":"Sample a sink's input briefly with a small per-interval cap","args":{"component":"datadog_logs","duration_ms":1000,"limit":20}}],"search_terms":["logs stopped flowing","log pipeline"],"command":{"binary":"vector","argv":["tap","--duration-ms","{{ args.duration_ms }}","--limit","{{ args.limit }}","--quiet","--format","json","--outputs-of","{{ args.component }}"]}},{"id":"vector.validate","title":"vector validate --no-environment","summary":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","description":"Validate a Vector config file offline — checks syntax and topology. Runs with --no-environment, so it checks structure only and skips all network sink healthchecks and environment probing — it never connects to anything. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads and parses a Vector config file on the runner host.","Read-only — no network healthchecks (--no-environment), no reload."],"args":[{"name":"config_path","type":"string","required":false,"default":"/etc/vector/vector.yaml","description":"Path to the Vector config file to validate.","validation":{"pattern":"^/[A-Za-z0-9._/-]{1,256}$","allowed_prefixes":["/etc/vector/"]}}],"examples":[{"title":"Validate the default config","args":{}},{"title":"Validate a specific config file","args":{"config_path":"/etc/vector/pipelines/api.yaml"}}],"search_terms":[],"command":{"binary":"vector","argv":["validate","--no-environment","{{ args.config_path }}"]}},{"id":"vector.version","title":"vector --version","summary":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","description":"Print the Vector binary version and build metadata. Run this FIRST: it tells you whether the observability API is GraphQL (Vector <= 0.54) or gRPC (>= 0.55, April 2026). That determines whether the GraphQL component_metrics action will work or 404. Talks only to the local binary — needs no API.","kind":"exec","risk":"low","side_effects":["Reads the local Vector binary version.","Read-only."],"args":[],"examples":[{"title":"Show version (and pick GraphQL vs gRPC)","args":{}}],"search_terms":[],"command":{"binary":"vector","argv":["--version"]}}]}],"retired_below":"0.1.3"},{"id":"victorialogs","name":"VictoriaLogs queries","version":"0.1.12","description":"Read-only LogsQL access to VictoriaLogs over its HTTP API: search log entries, hit histograms over time, stats aggregations (instant + range), and field / stream discovery. Every request has an enforced trailing time window. One base URL serves single-node and vmauth-fronted deployments; multitenancy via optional headers.","vendor":"emisar","homepage":"https://emisar.dev/packs/victorialogs","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/victorialogs","content_hash":"sha256:4ce531f806165c62eddb661b5358ca23a5a9a83e5e7be0b90cb63f1922fc4e2c","tarball_url":"https://registry.emisar.dev/v1/packs/victorialogs/0.1.12/4ce531f806165c62eddb661b5358ca23a5a9a83e5e7be0b90cb63f1922fc4e2c/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["victoria-logs","victoria-logs-prod","vlselect","vlselect-prod"],"ports":[9428]},"setup":{"summary":"Every action calls the VictoriaLogs LogsQL HTTP API at `$VL_URL` via curl on the runner host. Point `VL_URL` at the base URL (scheme + host + port); each action appends /select/logsql/.... Set `VL_BEARER_TOKEN` if the endpoint sits behind vmauth, and `VL_ACCOUNT_ID` / `VL_PROJECT_ID` to target a non-default tenant.","env":[{"name":"VL_URL","description":"VictoriaLogs base URL — scheme, host, and port, with no trailing path. Behind vmauth, include whatever route prefix maps to the backend.","default":"http://127.0.0.1:9428","example":"http://victoria-logs:9428"},{"name":"VL_BEARER_TOKEN","description":"Optional bearer token for vmauth-protected endpoints. Sent as \"Authorization: Bearer <token>\" over curl stdin, so it never appears in the process arguments or the audit log."},{"name":"VL_ACCOUNT_ID","description":"Tenant AccountID header. Defaults to 0 when unset."},{"name":"VL_PROJECT_ID","description":"Tenant ProjectID header. Defaults to 0 when unset."}],"notes":["Any of `VL_URL` / `VL_BEARER_TOKEN` / `VL_ACCOUNT_ID` / `VL_PROJECT_ID` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Every query has a trailing `window` (default 1h, maximum 24h), enforced with both the HTTP range and an unconditional `_time` extra filter. A LogsQL `_time` filter may narrow that window but cannot widen it. `vl.hits` and `vl.stats_query_range` are also limited to 10,081 buckets.","These bounds require VictoriaLogs 1.8.0 or newer, where HTTP extra filters propagate to every subquery. Requests also carry a 30-second provider-side timeout; query cardinality can still add cost.","Tenancy: the default tenant is AccountID=0 / ProjectID=0. Set `VL_ACCOUNT_ID` / `VL_PROJECT_ID` to target another; they are sent as headers over curl stdin.","Every action is a read-only GET — none ingest, delete, or mutate logs. No token or tenant header is sent unless its env var is set."],"verify":"vl.field_names"},"actions":[{"id":"vl.field_names","title":"GET /select/logsql/field_names","summary":"List the log field names matching a query, each with a hit count. Use to discover what fields exist before querying. Doubles as the pack's connectivity check.","description":"List the log field names matching a query, each with a hit count. Use to discover what fields exist before querying. Doubles as the pack's connectivity check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"All field names","args":{}}],"search_terms":[]},{"id":"vl.field_values","title":"GET /select/logsql/field_values","summary":"List the most frequent values of one log field, each with a hit count. Use to enumerate levels, namespaces, hosts, or any other dimension. Rated medium because the field argument accepts _msg, returning raw log message text (matching vl.query) that no redaction list can enumerate.","description":"List the most frequent values of one log field, each with a hit count. Use to enumerate levels, namespaces, hosts, or any other dimension. Rated medium because the field argument accepts _msg, returning raw log message text (matching vl.query) that no redaction list can enumerate.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"field","type":"string","required":true,"description":"Field name to enumerate values for, e.g. level, app, _stream.","validation":{"pattern":"^\\S{1,256}$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of values to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Distinct log levels","args":{"field":"level"}}],"search_terms":[]},{"id":"vl.hits","title":"GET /select/logsql/hits","summary":"Count log entries matching a LogsQL query, bucketed over time by step — the histogram behind \"how many errors per hour?\". The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 buckets.","description":"Count log entries matching a LogsQL query, bucketed over time by step — the histogram behind \"how many errors per hour?\". The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 buckets.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL query to count, e.g. error or level:error.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"step","type":"string","required":false,"default":"1h","description":"Bucket granularity. Window / step may produce at most 10,081 buckets.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}}],"examples":[{"title":"Errors per hour over the last day","args":{"query":"error","step":"1h","window":"24h"}}],"search_terms":["error rate","log volume"]},{"id":"vl.query","title":"GET /select/logsql/query","summary":"Run a LogsQL query and return matching log entries as newline-delimited JSON. Every request has a trailing window ending now, limited to 24 hours; the limit arg caps how many entries come back.","description":"Run a LogsQL query and return matching log entries as newline-delimited JSON. Every request has a trailing window ending now, limited to 24 hours; the limit arg caps how many entries come back.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only — never ingests or deletes logs."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL query, e.g. error, or {app=\"api\"} | stats by (level) count().","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log entries to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Recent errors","args":{"query":"error","window":"15m"}},{"title":"Errors for one app, newest first","args":{"limit":50,"query":"level:error app:api | sort by (_time) desc","window":"1h"}}],"search_terms":["log search","search logs","grep logs"]},{"id":"vl.stats_query","title":"GET /select/logsql/stats_query","summary":"Show instant stats over logs — a LogsQL query containing a \"| stats\" pipe, evaluated at one point in time and returned in Prometheus instant-query format. Use for totals like counts or sums grouped by a field.","description":"Show instant stats over logs — a LogsQL query containing a \"| stats\" pipe, evaluated at one point in time and returned in Prometheus instant-query format. Use for totals like counts or sums grouped by a field.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL with a | stats pipe, e.g. * | stats by (level) count().","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"Log count by level in the last hour","args":{"query":"* | stats by (level) count() logs","window":"1h"}}],"search_terms":[]},{"id":"vl.stats_query_range","title":"GET /select/logsql/stats_query_range","summary":"Show stats over logs across a time range — a LogsQL query containing a \"| stats\" pipe, evaluated at each step and returned in Prometheus range-query (matrix) format. The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 evaluation timestamps.","description":"Show stats over logs across a time range — a LogsQL query containing a \"| stats\" pipe, evaluated at each step and returned in Prometheus range-query (matrix) format. The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 evaluation timestamps.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL with a | stats pipe, e.g. * | stats count() logs.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"step","type":"string","required":false,"default":"1h","description":"Interval between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}}],"examples":[{"title":"Hourly error count over 6h","args":{"query":"error | stats count() errors","step":"1h","window":"6h"}}],"search_terms":[]},{"id":"vl.streams","title":"GET /select/logsql/streams","summary":"List the log streams matching a query, each with a hit count. A stream is the set of logs sharing the same stream labels (app, host, container, …). Use to see which sources are sending logs.","description":"List the log streams matching a query, each with a hit count. A stream is the set of logs sharing the same stream labels (app, host, container, …). Use to see which sources are sending logs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of streams to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Active log streams","args":{}}],"search_terms":["logs stopped","missing logs","ingestion stopped"]}],"previous_versions":[{"version":"0.1.11","content_hash":"sha256:4af52c9af40052576ad55fa9f6c366e6b41467e7a9b6403d7f067f5f680f1afb","tarball_url":"https://registry.emisar.dev/v1/packs/victorialogs/0.1.11/4af52c9af40052576ad55fa9f6c366e6b41467e7a9b6403d7f067f5f680f1afb/pack.tar.gz","actions":[{"id":"vl.field_names","title":"GET /select/logsql/field_names","summary":"List the log field names matching a query, each with a hit count. Use to discover what fields exist before querying. Doubles as the pack's connectivity check.","description":"List the log field names matching a query, each with a hit count. Use to discover what fields exist before querying. Doubles as the pack's connectivity check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"All field names","args":{}}],"search_terms":[]},{"id":"vl.field_values","title":"GET /select/logsql/field_values","summary":"List the most frequent values of one log field, each with a hit count. Use to enumerate levels, namespaces, hosts, or any other dimension.","description":"List the most frequent values of one log field, each with a hit count. Use to enumerate levels, namespaces, hosts, or any other dimension.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"field","type":"string","required":true,"description":"Field name to enumerate values for, e.g. level, app, _stream.","validation":{"pattern":"^\\S{1,256}$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of values to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Distinct log levels","args":{"field":"level"}}],"search_terms":[]},{"id":"vl.hits","title":"GET /select/logsql/hits","summary":"Count log entries matching a LogsQL query, bucketed over time by step — the histogram behind \"how many errors per hour?\". The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 buckets.","description":"Count log entries matching a LogsQL query, bucketed over time by step — the histogram behind \"how many errors per hour?\". The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 buckets.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL query to count, e.g. error or level:error.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"step","type":"string","required":false,"default":"1h","description":"Bucket granularity. Window / step may produce at most 10,081 buckets.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}}],"examples":[{"title":"Errors per hour over the last day","args":{"query":"error","step":"1h","window":"24h"}}],"search_terms":["error rate","log volume"]},{"id":"vl.query","title":"GET /select/logsql/query","summary":"Run a LogsQL query and return matching log entries as newline-delimited JSON. Every request has a trailing window ending now, limited to 24 hours; the limit arg caps how many entries come back.","description":"Run a LogsQL query and return matching log entries as newline-delimited JSON. Every request has a trailing window ending now, limited to 24 hours; the limit arg caps how many entries come back.","kind":"script","risk":"medium","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only — never ingests or deletes logs."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL query, e.g. error, or {app=\"api\"} | stats by (level) count().","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log entries to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Recent errors","args":{"query":"error","window":"15m"}},{"title":"Errors for one app, newest first","args":{"limit":50,"query":"level:error app:api | sort by (_time) desc","window":"1h"}}],"search_terms":["log search","search logs","grep logs"]},{"id":"vl.stats_query","title":"GET /select/logsql/stats_query","summary":"Show instant stats over logs — a LogsQL query containing a \"| stats\" pipe, evaluated at one point in time and returned in Prometheus instant-query format. Use for totals like counts or sums grouped by a field.","description":"Show instant stats over logs — a LogsQL query containing a \"| stats\" pipe, evaluated at one point in time and returned in Prometheus instant-query format. Use for totals like counts or sums grouped by a field.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL with a | stats pipe, e.g. * | stats by (level) count().","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"Log count by level in the last hour","args":{"query":"* | stats by (level) count() logs","window":"1h"}}],"search_terms":[]},{"id":"vl.stats_query_range","title":"GET /select/logsql/stats_query_range","summary":"Show stats over logs across a time range — a LogsQL query containing a \"| stats\" pipe, evaluated at each step and returned in Prometheus range-query (matrix) format. The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 evaluation timestamps.","description":"Show stats over logs across a time range — a LogsQL query containing a \"| stats\" pipe, evaluated at each step and returned in Prometheus range-query (matrix) format. The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 evaluation timestamps.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL with a | stats pipe, e.g. * | stats count() logs.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"step","type":"string","required":false,"default":"1h","description":"Interval between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}}],"examples":[{"title":"Hourly error count over 6h","args":{"query":"error | stats count() errors","step":"1h","window":"6h"}}],"search_terms":[]},{"id":"vl.streams","title":"GET /select/logsql/streams","summary":"List the log streams matching a query, each with a hit count. A stream is the set of logs sharing the same stream labels (app, host, container, …). Use to see which sources are sending logs.","description":"List the log streams matching a query, each with a hit count. A stream is the set of logs sharing the same stream labels (app, host, container, …). Use to see which sources are sending logs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of streams to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Active log streams","args":{}}],"search_terms":["logs stopped","missing logs","ingestion stopped"]}]},{"version":"0.1.9","content_hash":"sha256:a75242a03a1fc8058ff03a838891719c5501ba9b7b50ebaafa68e4f7a27a4720","tarball_url":"https://registry.emisar.dev/v1/packs/victorialogs/0.1.9/a75242a03a1fc8058ff03a838891719c5501ba9b7b50ebaafa68e4f7a27a4720/pack.tar.gz","actions":[{"id":"vl.field_names","title":"GET /select/logsql/field_names","summary":"List the log field names matching a query, each with a hit count. Use to discover what fields exist before querying. Doubles as the pack's connectivity check.","description":"List the log field names matching a query, each with a hit count. Use to discover what fields exist before querying. Doubles as the pack's connectivity check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"All field names","args":{}}],"search_terms":[]},{"id":"vl.field_values","title":"GET /select/logsql/field_values","summary":"List the most frequent values of one log field, each with a hit count. Use to enumerate levels, namespaces, hosts, or any other dimension.","description":"List the most frequent values of one log field, each with a hit count. Use to enumerate levels, namespaces, hosts, or any other dimension.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"field","type":"string","required":true,"description":"Field name to enumerate values for, e.g. level, app, _stream.","validation":{"pattern":"^\\S{1,256}$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of values to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Distinct log levels","args":{"field":"level"}}],"search_terms":[]},{"id":"vl.hits","title":"GET /select/logsql/hits","summary":"Count log entries matching a LogsQL query, bucketed over time by step — the histogram behind \"how many errors per hour?\". The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 buckets.","description":"Count log entries matching a LogsQL query, bucketed over time by step — the histogram behind \"how many errors per hour?\". The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 buckets.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL query to count, e.g. error or level:error.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"step","type":"string","required":false,"default":"1h","description":"Bucket granularity. Window / step may produce at most 10,081 buckets.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}}],"examples":[{"title":"Errors per hour over the last day","args":{"query":"error","step":"1h","window":"24h"}}],"search_terms":["error rate","log volume"]},{"id":"vl.query","title":"GET /select/logsql/query","summary":"Run a LogsQL query and return matching log entries as newline-delimited JSON. Every request has a trailing window ending now, limited to 24 hours; the limit arg caps how many entries come back.","description":"Run a LogsQL query and return matching log entries as newline-delimited JSON. Every request has a trailing window ending now, limited to 24 hours; the limit arg caps how many entries come back.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only — never ingests or deletes logs."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL query, e.g. error, or {app=\"api\"} | stats by (level) count().","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of log entries to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Recent errors","args":{"query":"error","window":"15m"}},{"title":"Errors for one app, newest first","args":{"limit":50,"query":"level:error app:api | sort by (_time) desc","window":"1h"}}],"search_terms":["log search","search logs","grep logs"]},{"id":"vl.stats_query","title":"GET /select/logsql/stats_query","summary":"Show instant stats over logs — a LogsQL query containing a \"| stats\" pipe, evaluated at one point in time and returned in Prometheus instant-query format. Use for totals like counts or sums grouped by a field.","description":"Show instant stats over logs — a LogsQL query containing a \"| stats\" pipe, evaluated at one point in time and returned in Prometheus instant-query format. Use for totals like counts or sums grouped by a field.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL with a | stats pipe, e.g. * | stats by (level) count().","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"Log count by level in the last hour","args":{"query":"* | stats by (level) count() logs","window":"1h"}}],"search_terms":[]},{"id":"vl.stats_query_range","title":"GET /select/logsql/stats_query_range","summary":"Show stats over logs across a time range — a LogsQL query containing a \"| stats\" pipe, evaluated at each step and returned in Prometheus range-query (matrix) format. The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 evaluation timestamps.","description":"Show stats over logs across a time range — a LogsQL query containing a \"| stats\" pipe, evaluated at each step and returned in Prometheus range-query (matrix) format. The trailing window is limited to 24 hours and the window-to-step ratio to 10,081 evaluation timestamps.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":true,"description":"LogsQL with a | stats pipe, e.g. * | stats count() logs.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"step","type":"string","required":false,"default":"1h","description":"Interval between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}}],"examples":[{"title":"Hourly error count over 6h","args":{"query":"error | stats count() errors","step":"1h","window":"6h"}}],"search_terms":[]},{"id":"vl.streams","title":"GET /select/logsql/streams","summary":"List the log streams matching a query, each with a hit count. A stream is the set of logs sharing the same stream labels (app, host, container, …). Use to see which sources are sending logs.","description":"List the log streams matching a query, each with a hit count. A stream is the set of logs sharing the same stream labels (app, host, container, …). Use to see which sources are sending logs.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaLogs query API.","Read-only."],"args":[{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing search window ending now, up to 24h.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdw]$"}},{"name":"query","type":"string","required":false,"default":"*","description":"LogsQL scope, e.g. app:api. Defaults to all logs in the bounded window.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":100,"description":"Maximum number of streams to return.","validation":{"min":1,"max":10000}}],"examples":[{"title":"Active log streams","args":{}}],"search_terms":["logs stopped","missing logs","ingestion stopped"]}]}],"retired_below":"0.1.9"},{"id":"victoriametrics","name":"VictoriaMetrics queries","version":"0.1.11","description":"Read-only PromQL / MetricsQL access to VictoriaMetrics over its HTTP API: instant and range queries, series and label discovery, and the VM-specific status endpoints (TSDB cardinality, active queries, top queries). One base URL serves single-node, cluster (vmselect), and vmauth-fronted deployments.","vendor":"emisar","homepage":"https://emisar.dev/packs/victoriametrics","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/victoriametrics","content_hash":"sha256:d720f15ec3d248b5682cfc3ad7fd72e8c1f9866d3c70f3cd52125c521c5cee7e","tarball_url":"https://registry.emisar.dev/v1/packs/victoriametrics/0.1.11/d720f15ec3d248b5682cfc3ad7fd72e8c1f9866d3c70f3cd52125c521c5cee7e/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["victoria-metrics","victoria-metrics-prod","vmselect","vmselect-prod"],"ports":[8428,8481]},"setup":{"summary":"Every action calls the VictoriaMetrics HTTP API at `$VM_URL` via curl on the runner host. Point `VM_URL` at the query base URL including any /prometheus (single-node) or /select/<accountID>/prometheus (cluster) prefix; each action appends /api/v1/.... Set `VM_BEARER_TOKEN` if the endpoint sits behind vmauth or another bearer-token proxy.","env":[{"name":"VM_URL","description":"Query base URL — scheme, host, port, and the prefix up to (but not including) /api/v1. Single-node ends in /prometheus; cluster reads go through vmselect at /select/<accountID>/prometheus.","default":"http://127.0.0.1:8428","example":"http://victoria-metrics:8428/prometheus"},{"name":"VM_BEARER_TOKEN","description":"Optional bearer token for vmauth-protected endpoints. Sent as \"Authorization: Bearer <token>\" over curl stdin, so it never appears in the process arguments or the audit log."}],"notes":["Any of `VM_URL` / `VM_BEARER_TOKEN` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Single-node URL: http://<host>:8428/prometheus. Cluster (vmselect) reads: http://<vmselect>:8481/select/<accountID>/prometheus. Behind vmauth: use its base URL plus whatever route prefix maps to the backend.","Every action is a read-only GET — none write, delete, or mutate series. Range queries are limited to 7 days and 10,081 outer evaluation timestamps per returned series, with a 30-second provider-side timeout. This preserves a full week at one-minute resolution; query cardinality, range-vector lookbacks, and subqueries can still add cost.","No token is sent unless `VM_BEARER_TOKEN` is set. For basic-auth fronts, embed credentials in `VM_URL` (http://user:pass@host) or terminate auth at a trusted side door."],"verify":"vm.labels"},"actions":[{"id":"vm.active_queries","title":"GET /api/v1/status/active_queries","summary":"List the queries VictoriaMetrics is executing right now — their text, how long they have been running, and the client address. Use to catch a runaway or slow query in the act.","description":"List the queries VictoriaMetrics is executing right now — their text, how long they have been running, and the client address. Use to catch a runaway or slow query in the act.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[],"examples":[{"title":"Currently running queries","args":{}}],"search_terms":["runaway query","query stuck"]},{"id":"vm.label_values","title":"GET /api/v1/label/<name>/values","summary":"List all values for one label. Use to enumerate jobs, instances, or any other dimension before filtering a query.","description":"List all values for one label. Use to enumerate jobs, instances, or any other dimension before filtering a query.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"label","type":"string","required":true,"description":"Label name to enumerate values for, e.g. job, instance.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}}],"examples":[{"title":"All scrape jobs","args":{"label":"job"}}],"search_terms":[]},{"id":"vm.labels","title":"GET /api/v1/labels","summary":"List every label name present in VictoriaMetrics over the default time range. Use to discover the available dimensions. Doubles as the pack's connectivity check.","description":"List every label name present in VictoriaMetrics over the default time range. Use to discover the available dimensions. Doubles as the pack's connectivity check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[],"examples":[{"title":"All label names","args":{}}],"search_terms":[]},{"id":"vm.query_instant","title":"GET /api/v1/query","summary":"Run an instant PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression at the current time. Use to answer \"what is X right now?\".","description":"Run an instant PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression at the current time. Use to answer \"what is X right now?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only — never writes or deletes series."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL or MetricsQL expression to evaluate now.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"Targets that are down","args":{"query":"up == 0"}},{"title":"Total scrape targets","args":{"query":"count(up)"}}],"search_terms":[]},{"id":"vm.query_range","title":"GET /api/v1/query_range","summary":"Run a range PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression across a trailing window ending now, limited to 7 days and 10,081 outer evaluation timestamps per returned series. Use for trends and rates over time. Query cardinality and inner ranges can still make this expensive.","description":"Run a range PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression across a trailing window ending now, limited to 7 days and 10,081 outer evaluation timestamps per returned series. Use for trends and rates over time. Query cardinality and inner ranges can still make this expensive.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Reads a range of samples — may be expensive on large series."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL or MetricsQL expression.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing window ending now, up to 7d, e.g. 30m, 1h, 6h, 24h, 7d.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdwy]$"}},{"name":"step","type":"string","required":false,"default":"60s","description":"Resolution between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[smh]$"}}],"examples":[{"title":"1h request rate","args":{"query":"sum(rate(vm_http_requests_total[5m]))","step":"60s","window":"1h"}}],"search_terms":[]},{"id":"vm.series","title":"GET /api/v1/series","summary":"List the time series matching a selector — the label sets that exist, not their samples. Use to discover what is stored before writing a query.","description":"List the time series matching a selector — the label sets that exist, not their samples. Use to discover what is stored before writing a query.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"match","type":"string","required":true,"description":"Series selector, e.g. {__name__=~\"node_.*\", job=\"node\"}.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":1000,"description":"Maximum number of series to return.","validation":{"min":1,"max":100000}}],"examples":[{"title":"All series for a metric","args":{"match":"node_cpu_seconds_total"}}],"search_terms":[]},{"id":"vm.top_queries","title":"GET /api/v1/status/top_queries","summary":"List the most frequent and most expensive queries VictoriaMetrics has seen — topByCount, topByAvgDuration, and topBySumDuration. Use to find what to optimize or rate-limit.","description":"List the most frequent and most expensive queries VictoriaMetrics has seen — topByCount, topByAvgDuration, and topBySumDuration. Use to find what to optimize or rate-limit.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"top_n","type":"integer","required":false,"default":20,"description":"Number of queries to return per list.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top 20 queries","args":{}}],"search_terms":["slow queries"]},{"id":"vm.tsdb_status","title":"GET /api/v1/status/tsdb","summary":"Show TSDB cardinality stats — the metric names, label pairs, and label values with the highest series counts. The first stop when cardinality or memory is climbing.","description":"Show TSDB cardinality stats — the metric names, label pairs, and label values with the highest series counts. The first stop when cardinality or memory is climbing.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"top_n","type":"integer","required":false,"default":10,"description":"Number of top entries to return per category.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top cardinality contributors","args":{}}],"search_terms":["metrics missing","series gone","cardinality explosion","too many series"]}],"previous_versions":[{"version":"0.1.10","content_hash":"sha256:5a3584f137590a6716bed7ab7ed89aabbdfe6f73d33740d120318a9ca1c8c087","tarball_url":"https://registry.emisar.dev/v1/packs/victoriametrics/0.1.10/5a3584f137590a6716bed7ab7ed89aabbdfe6f73d33740d120318a9ca1c8c087/pack.tar.gz","actions":[{"id":"vm.active_queries","title":"GET /api/v1/status/active_queries","summary":"List the queries VictoriaMetrics is executing right now — their text, how long they have been running, and the client address. Use to catch a runaway or slow query in the act.","description":"List the queries VictoriaMetrics is executing right now — their text, how long they have been running, and the client address. Use to catch a runaway or slow query in the act.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[],"examples":[{"title":"Currently running queries","args":{}}],"search_terms":["runaway query","query stuck"]},{"id":"vm.label_values","title":"GET /api/v1/label/<name>/values","summary":"List all values for one label. Use to enumerate jobs, instances, or any other dimension before filtering a query.","description":"List all values for one label. Use to enumerate jobs, instances, or any other dimension before filtering a query.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"label","type":"string","required":true,"description":"Label name to enumerate values for, e.g. job, instance.","validation":{"pattern":"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$"}}],"examples":[{"title":"All scrape jobs","args":{"label":"job"}}],"search_terms":[]},{"id":"vm.labels","title":"GET /api/v1/labels","summary":"List every label name present in VictoriaMetrics over the default time range. Use to discover the available dimensions. Doubles as the pack's connectivity check.","description":"List every label name present in VictoriaMetrics over the default time range. Use to discover the available dimensions. Doubles as the pack's connectivity check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[],"examples":[{"title":"All label names","args":{}}],"search_terms":[]},{"id":"vm.query_instant","title":"GET /api/v1/query","summary":"Run an instant PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression at the current time. Use to answer \"what is X right now?\".","description":"Run an instant PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression at the current time. Use to answer \"what is X right now?\".","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only — never writes or deletes series."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL or MetricsQL expression to evaluate now.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}}],"examples":[{"title":"Targets that are down","args":{"query":"up == 0"}},{"title":"Total scrape targets","args":{"query":"count(up)"}}],"search_terms":[]},{"id":"vm.query_range","title":"GET /api/v1/query_range","summary":"Run a range PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression across a trailing window ending now, limited to 7 days and 10,081 outer evaluation timestamps per returned series. Use for trends and rates over time. Query cardinality and inner ranges can still make this expensive.","description":"Run a range PromQL/MetricsQL query against VictoriaMetrics — evaluates one expression across a trailing window ending now, limited to 7 days and 10,081 outer evaluation timestamps per returned series. Use for trends and rates over time. Query cardinality and inner ranges can still make this expensive.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Reads a range of samples — may be expensive on large series."],"args":[{"name":"query","type":"string","required":true,"description":"PromQL or MetricsQL expression.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"window","type":"string","required":false,"default":"1h","description":"Trailing window ending now, up to 7d, e.g. 30m, 1h, 6h, 24h, 7d.","validation":{"pattern":"^[1-9][0-9]{0,4}[smhdwy]$"}},{"name":"step","type":"string","required":false,"default":"60s","description":"Resolution between points. Window / step may produce at most 10,081 timestamps.","validation":{"pattern":"^[1-9][0-9]{0,4}[smh]$"}}],"examples":[{"title":"1h request rate","args":{"query":"sum(rate(vm_http_requests_total[5m]))","step":"60s","window":"1h"}}],"search_terms":[]},{"id":"vm.series","title":"GET /api/v1/series","summary":"List the time series matching a selector — the label sets that exist, not their samples. Use to discover what is stored before writing a query.","description":"List the time series matching a selector — the label sets that exist, not their samples. Use to discover what is stored before writing a query.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"match","type":"string","required":true,"description":"Series selector, e.g. {__name__=~\"node_.*\", job=\"node\"}.","validation":{"pattern":"^[\\s\\S]{1,1000}$"}},{"name":"limit","type":"integer","required":false,"default":1000,"description":"Maximum number of series to return.","validation":{"min":1,"max":100000}}],"examples":[{"title":"All series for a metric","args":{"match":"node_cpu_seconds_total"}}],"search_terms":[]},{"id":"vm.top_queries","title":"GET /api/v1/status/top_queries","summary":"List the most frequent and most expensive queries VictoriaMetrics has seen — topByCount, topByAvgDuration, and topBySumDuration. Use to find what to optimize or rate-limit.","description":"List the most frequent and most expensive queries VictoriaMetrics has seen — topByCount, topByAvgDuration, and topBySumDuration. Use to find what to optimize or rate-limit.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"top_n","type":"integer","required":false,"default":20,"description":"Number of queries to return per list.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top 20 queries","args":{}}],"search_terms":["slow queries"]},{"id":"vm.tsdb_status","title":"GET /api/v1/status/tsdb","summary":"Show TSDB cardinality stats — the metric names, label pairs, and label values with the highest series counts. The first stop when cardinality or memory is climbing.","description":"Show TSDB cardinality stats — the metric names, label pairs, and label values with the highest series counts. The first stop when cardinality or memory is climbing.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the VictoriaMetrics query API.","Read-only."],"args":[{"name":"top_n","type":"integer","required":false,"default":10,"description":"Number of top entries to return per category.","validation":{"min":1,"max":100}}],"examples":[{"title":"Top cardinality contributors","args":{}}],"search_terms":["metrics missing","series gone","cardinality explosion","too many series"]}]}],"retired_below":"0.1.10"},{"id":"wireguard","name":"WireGuard VPN","version":"0.1.9","description":"WireGuard state — interfaces, peers, transfer counts, last handshakes — plus operator actions: bring iface up/down via wg-quick, remove a peer from a live iface. Use to debug connectivity or evict a compromised peer.","vendor":"emisar","homepage":"https://emisar.dev/packs/wireguard","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/wireguard","content_hash":"sha256:64a57ba29b01695488783bce307691c4b72aca49b51b6aa288e1b707d50592ec","tarball_url":"https://registry.emisar.dev/v1/packs/wireguard/0.1.9/64a57ba29b01695488783bce307691c4b72aca49b51b6aa288e1b707d50592ec/pack.tar.gz","requires":{"os":["linux"],"binaries":["wg"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Reads and manages WireGuard interfaces on the local runner host — no credentials needed.","notes":["showconf's PrivateKey/PresharedKey lines are masked at the source before output leaves the host."],"host_access":[{"actions":["wg.show","wg.show_transfer","wg.show_latest_handshakes","wg.show_endpoints","wg.showconf","wg.set_peer_remove"],"requirement":"Read or change WireGuard interface state with CAP_NET_ADMIN.","recipes":[{"name":"Grant CAP_NET_ADMIN to the Emisar service","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'AmbientCapabilities=CAP_NET_ADMIN' | sudo tee /etc/systemd/system/emisar.service.d/10-wireguard-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["systemctl show emisar --property=AmbientCapabilities --value | grep -Fwi cap_net_admin"],"impact":"Every Emisar action on this runner inherits CAP_NET_ADMIN and can change network interfaces, routes, firewall rules, and WireGuard peers outside this pack."}]},{"actions":["wg.quick_up","wg.quick_down"],"requirement":"Run wg-quick, including its host networking and configured hook commands, as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-wireguard-root.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. wg-quick also executes every PreUp, PostUp, PreDown, and PostDown command authored in the interface configuration."}]}],"verify":"wg.show"},"actions":[{"id":"wg.quick_down","title":"wg-quick down <iface>","summary":"Tear down a WireGuard interface. All active sessions through it drop. PostDown rules run (typically cleaning up routes/firewall).","description":"Tear down a WireGuard interface. All active sessions through it drop. PostDown rules run (typically cleaning up routes/firewall).","kind":"exec","risk":"high","side_effects":["Interface destroyed.","All tunnel sessions terminated.","Routing + firewall rules cleaned up by PostDown."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"Tear down wg0","args":{"iface":"wg0"}}],"search_terms":[],"command":{"binary":"wg-quick","argv":["down","{{ args.iface }}"]}},{"id":"wg.quick_up","title":"wg-quick up <iface>","summary":"Bring up a WireGuard interface defined in /etc/wireguard/<iface>.conf. Applies the address, peers, and PostUp rules.","description":"Bring up a WireGuard interface defined in /etc/wireguard/<iface>.conf. Applies the address, peers, and PostUp rules.","kind":"exec","risk":"high","side_effects":["Interface comes up with the configured peers.","Routing table changes.","PostUp scripts (if any) run."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (matches /etc/wireguard/<iface>.conf).","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"Bring up wg0","args":{"iface":"wg0"}}],"search_terms":[],"command":{"binary":"wg-quick","argv":["up","{{ args.iface }}"]}},{"id":"wg.set_peer_remove","title":"wg set <iface> peer <pubkey> remove","summary":"Remove one peer from a running WireGuard interface. Its tunnel sessions drop. The peer can no longer connect until added back (or the config file is reloaded).","description":"Remove one peer from a running WireGuard interface. Its tunnel sessions drop. The peer can no longer connect until added back (or the config file is reloaded).","kind":"exec","risk":"high","side_effects":["Peer removed from runtime state.","That peer's traffic stops flowing.","Change is runtime-only; iface config file unchanged."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}},{"name":"pubkey","type":"string","required":true,"description":"Peer's base64 public key.","validation":{"pattern":"^[A-Za-z0-9+/]{43}=$"}}],"examples":[{"title":"Kick a peer","args":{"iface":"wg0","pubkey":"abcDEF1234567890abcDEF1234567890abcDEF12345="}}],"search_terms":[],"command":{"binary":"wg","argv":["set","{{ args.iface }}","peer","{{ args.pubkey }}","remove"]}},{"id":"wg.show","title":"wg show","summary":"List all interfaces with peers + endpoints + last-handshake.","description":"List all interfaces with peers + endpoints + last-handshake.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"All interfaces","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show"]}},{"id":"wg.show_endpoints","title":"wg show all endpoints","summary":"Show per-peer remote endpoint (last known).","description":"Show per-peer remote endpoint (last known).","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Endpoints","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","endpoints"]}},{"id":"wg.show_latest_handshakes","title":"wg show all latest-handshakes","summary":"Show per-peer epoch of last handshake. 0 means never seen.","description":"Show per-peer epoch of last handshake. 0 means never seen.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Handshakes","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","latest-handshakes"]}},{"id":"wg.show_transfer","title":"wg show all transfer","summary":"Show per-peer cumulative bytes rx/tx. Use to confirm \"is the tunnel actually carrying traffic?\".","description":"Show per-peer cumulative bytes rx/tx. Use to confirm \"is the tunnel actually carrying traffic?\".","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Transfer counts","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","transfer"]}},{"id":"wg.showconf","title":"wg showconf <iface>","summary":"Show the effective config for one WireGuard interface (`[Interface]`/`[Peer]` sections, peer pubkeys, allowed-ips, endpoints). PrivateKey and PresharedKey lines are masked at the source.","description":"Show the effective config for one WireGuard interface (`[Interface]`/`[Peer]` sections, peer pubkeys, allowed-ips, endpoints). PrivateKey and PresharedKey lines are masked at the source.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only.","`wg showconf` emits the interface PrivateKey and per-peer PresharedKey; the action masks both at the source before any output leaves the host."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"wg0 config","args":{"interface":"wg0"}}],"search_terms":[],"command":{"binary":"wg","argv":["showconf","{{ args.interface }}"]}}],"previous_versions":[{"version":"0.1.8","content_hash":"sha256:cabc8256149db3372bc7e571e726bec0e291cc9637fc3ae4dba70e5df6877b78","tarball_url":"https://registry.emisar.dev/v1/packs/wireguard/0.1.8/cabc8256149db3372bc7e571e726bec0e291cc9637fc3ae4dba70e5df6877b78/pack.tar.gz","actions":[{"id":"wg.quick_down","title":"wg-quick down <iface>","summary":"Tear down a WireGuard interface. All active sessions through it drop. PostDown rules run (typically cleaning up routes/firewall).","description":"Tear down a WireGuard interface. All active sessions through it drop. PostDown rules run (typically cleaning up routes/firewall).","kind":"exec","risk":"high","side_effects":["Interface destroyed.","All tunnel sessions terminated.","Routing + firewall rules cleaned up by PostDown."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"Tear down wg0","args":{"iface":"wg0"}}],"search_terms":[],"command":{"binary":"wg-quick","argv":["down","{{ args.iface }}"]}},{"id":"wg.quick_up","title":"wg-quick up <iface>","summary":"Bring up a WireGuard interface defined in /etc/wireguard/<iface>.conf. Applies the address, peers, and PostUp rules.","description":"Bring up a WireGuard interface defined in /etc/wireguard/<iface>.conf. Applies the address, peers, and PostUp rules.","kind":"exec","risk":"high","side_effects":["Interface comes up with the configured peers.","Routing table changes.","PostUp scripts (if any) run."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (matches /etc/wireguard/<iface>.conf).","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"Bring up wg0","args":{"iface":"wg0"}}],"search_terms":[],"command":{"binary":"wg-quick","argv":["up","{{ args.iface }}"]}},{"id":"wg.set_peer_remove","title":"wg set <iface> peer <pubkey> remove","summary":"Remove one peer from a running WireGuard interface. Its tunnel sessions drop. The peer can no longer connect until added back (or the config file is reloaded).","description":"Remove one peer from a running WireGuard interface. Its tunnel sessions drop. The peer can no longer connect until added back (or the config file is reloaded).","kind":"exec","risk":"high","side_effects":["Peer removed from runtime state.","That peer's traffic stops flowing.","Change is runtime-only; iface config file unchanged."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}},{"name":"pubkey","type":"string","required":true,"description":"Peer's base64 public key.","validation":{"pattern":"^[A-Za-z0-9+/]{43}=$"}}],"examples":[{"title":"Kick a peer","args":{"iface":"wg0","pubkey":"abcDEF1234567890abcDEF1234567890abcDEF12345="}}],"search_terms":[],"command":{"binary":"wg","argv":["set","{{ args.iface }}","peer","{{ args.pubkey }}","remove"]}},{"id":"wg.show","title":"wg show","summary":"List all interfaces with peers + endpoints + last-handshake.","description":"List all interfaces with peers + endpoints + last-handshake.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"All interfaces","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show"]}},{"id":"wg.show_endpoints","title":"wg show all endpoints","summary":"Show per-peer remote endpoint (last known).","description":"Show per-peer remote endpoint (last known).","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Endpoints","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","endpoints"]}},{"id":"wg.show_latest_handshakes","title":"wg show all latest-handshakes","summary":"Show per-peer epoch of last handshake. 0 means never seen.","description":"Show per-peer epoch of last handshake. 0 means never seen.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Handshakes","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","latest-handshakes"]}},{"id":"wg.show_transfer","title":"wg show all transfer","summary":"Show per-peer cumulative bytes rx/tx. Use to confirm \"is the tunnel actually carrying traffic?\".","description":"Show per-peer cumulative bytes rx/tx. Use to confirm \"is the tunnel actually carrying traffic?\".","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Transfer counts","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","transfer"]}},{"id":"wg.showconf","title":"wg showconf <iface>","summary":"Show the effective config for one WireGuard interface (`[Interface]`/`[Peer]` sections, peer pubkeys, allowed-ips, endpoints). PrivateKey and PresharedKey lines are masked at the source.","description":"Show the effective config for one WireGuard interface (`[Interface]`/`[Peer]` sections, peer pubkeys, allowed-ips, endpoints). PrivateKey and PresharedKey lines are masked at the source.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only.","`wg showconf` emits the interface PrivateKey and per-peer PresharedKey; the action masks both at the source before any output leaves the host."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"wg0 config","args":{"interface":"wg0"}}],"search_terms":[],"command":{"binary":"wg","argv":["showconf","{{ args.interface }}"]}}]},{"version":"0.1.7","content_hash":"sha256:0dcb405567a8b1ff9cfb5c1ec350eb01d1f92bb10b01d7e1d1fc93fe38548ff5","tarball_url":"https://registry.emisar.dev/v1/packs/wireguard/0.1.7/0dcb405567a8b1ff9cfb5c1ec350eb01d1f92bb10b01d7e1d1fc93fe38548ff5/pack.tar.gz","actions":[{"id":"wg.quick_down","title":"wg-quick down <iface>","summary":"Tear down a WireGuard interface. All active sessions through it drop. PostDown rules run (typically cleaning up routes/firewall).","description":"Tear down a WireGuard interface. All active sessions through it drop. PostDown rules run (typically cleaning up routes/firewall).","kind":"exec","risk":"high","side_effects":["Interface destroyed.","All tunnel sessions terminated.","Routing + firewall rules cleaned up by PostDown."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"Tear down wg0","args":{"iface":"wg0"}}],"search_terms":[],"command":{"binary":"wg-quick","argv":["down","{{ args.iface }}"]}},{"id":"wg.quick_up","title":"wg-quick up <iface>","summary":"Bring up a WireGuard interface defined in /etc/wireguard/<iface>.conf. Applies the address, peers, and PostUp rules.","description":"Bring up a WireGuard interface defined in /etc/wireguard/<iface>.conf. Applies the address, peers, and PostUp rules.","kind":"exec","risk":"high","side_effects":["Interface comes up with the configured peers.","Routing table changes.","PostUp scripts (if any) run."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name (matches /etc/wireguard/<iface>.conf).","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"Bring up wg0","args":{"iface":"wg0"}}],"search_terms":[],"command":{"binary":"wg-quick","argv":["up","{{ args.iface }}"]}},{"id":"wg.set_peer_remove","title":"wg set <iface> peer <pubkey> remove","summary":"Remove one peer from a running WireGuard interface. Its tunnel sessions drop. The peer can no longer connect until added back (or the config file is reloaded).","description":"Remove one peer from a running WireGuard interface. Its tunnel sessions drop. The peer can no longer connect until added back (or the config file is reloaded).","kind":"exec","risk":"high","side_effects":["Peer removed from runtime state.","That peer's traffic stops flowing.","Change is runtime-only; iface config file unchanged."],"args":[{"name":"iface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}},{"name":"pubkey","type":"string","required":true,"description":"Peer's base64 public key.","validation":{"pattern":"^[A-Za-z0-9+/]{43}=$"}}],"examples":[{"title":"Kick a peer","args":{"iface":"wg0","pubkey":"abcDEF1234567890abcDEF1234567890abcDEF12345="}}],"search_terms":[],"command":{"binary":"wg","argv":["set","{{ args.iface }}","peer","{{ args.pubkey }}","remove"]}},{"id":"wg.show","title":"wg show","summary":"List all interfaces with peers + endpoints + last-handshake.","description":"List all interfaces with peers + endpoints + last-handshake.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"All interfaces","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show"]}},{"id":"wg.show_endpoints","title":"wg show all endpoints","summary":"Show per-peer remote endpoint (last known).","description":"Show per-peer remote endpoint (last known).","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Endpoints","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","endpoints"]}},{"id":"wg.show_latest_handshakes","title":"wg show all latest-handshakes","summary":"Show per-peer epoch of last handshake. 0 means never seen.","description":"Show per-peer epoch of last handshake. 0 means never seen.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Handshakes","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","latest-handshakes"]}},{"id":"wg.show_transfer","title":"wg show all transfer","summary":"Show per-peer cumulative bytes rx/tx. Use to confirm \"is the tunnel actually carrying traffic?\".","description":"Show per-peer cumulative bytes rx/tx. Use to confirm \"is the tunnel actually carrying traffic?\".","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only."],"args":[],"examples":[{"title":"Transfer counts","args":{}}],"search_terms":[],"command":{"binary":"wg","argv":["show","all","transfer"]}},{"id":"wg.showconf","title":"wg showconf <iface>","summary":"Show the effective config for one WireGuard interface (`[Interface]`/`[Peer]` sections, peer pubkeys, allowed-ips, endpoints). PrivateKey and PresharedKey lines are masked at the source.","description":"Show the effective config for one WireGuard interface (`[Interface]`/`[Peer]` sections, peer pubkeys, allowed-ips, endpoints). PrivateKey and PresharedKey lines are masked at the source.","kind":"exec","risk":"low","side_effects":["One netlink query.","Read-only.","`wg showconf` emits the interface PrivateKey and per-peer PresharedKey; the action masks both at the source before any output leaves the host."],"args":[{"name":"interface","type":"string","required":true,"description":"Interface name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,14}$"}}],"examples":[{"title":"wg0 config","args":{"interface":"wg0"}}],"search_terms":[],"command":{"binary":"wg","argv":["showconf","{{ args.interface }}"]}}]}],"retired_below":"0.1.7"},{"id":"zfs","name":"ZFS pool + dataset operations","version":"0.1.13","description":"Pool status, dataset inventory, snapshot listing, scrub status, ARC stats, plus operator surface for storage incident response: scrub start/stop, clear pool errors, take/destroy snapshots, dataset rollback.","vendor":"emisar","homepage":"https://emisar.dev/packs/zfs","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/zfs","content_hash":"sha256:206b1362910344a1624fe67d650be4a8618d5bc8778c778d038fe95f25e012b1","tarball_url":"https://registry.emisar.dev/v1/packs/zfs/0.1.13/206b1362910344a1624fe67d650be4a8618d5bc8778c778d038fe95f25e012b1/pack.tar.gz","requires":{"os":["linux"],"binaries":["zpool","zfs"]},"detect":{"binaries":[],"processes":[],"ports":[]},"setup":{"summary":"Operates on the ZFS pools of the local runner host — no credentials needed.","notes":["Status/list/iostat reads work as any user that can run zpool/zfs."],"host_access":[{"actions":["zfs.start_scrub","zfs.take_snapshot","zfs.scrub_stop","zfs.clear_pool_errors","zfs.snapshot_destroy","zfs.dataset_rollback"],"requirement":"Change ZFS pool and dataset state as root.","recipes":[{"name":"Run the Emisar service as root","commands":["sudo install -d -m 0755 /etc/systemd/system/emisar.service.d","printf '%s\\n' '[Service]' 'User=root' 'Group=root' | sudo tee /etc/systemd/system/emisar.service.d/10-zfs-host-access.conf >/dev/null","sudo systemctl daemon-reload","sudo systemctl restart emisar"],"verify":["test \"$(systemctl show emisar --property=User --value)\" = root"],"impact":"Every Emisar action on this runner executes as root. ZFS mutations can destroy snapshots, roll datasets back, or change pool recovery state."}]}],"verify":"zfs.pool_list"},"actions":[{"id":"zfs.arc_stats","title":"/proc/spl/kstat/zfs/arcstats","summary":"Show ARC cache statistics — size, hit ratio, eviction counts.","description":"Show ARC cache statistics — size, hit ratio, eviction counts.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"ARC stats","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/spl/kstat/zfs/arcstats"]}},{"id":"zfs.clear_pool_errors","title":"zpool clear <pool> [device]","summary":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","description":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","kind":"exec","risk":"high","side_effects":["Read, write, checksum error counters reset.","FAULTED devices marked ONLINE if reachable.","Resilvering may start if needed."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"device","type":"string","required":false,"default":"","description":"Specific device (empty for all).","validation":{"pattern":"^([a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127})?$"}}],"examples":[{"title":"Clear all errors on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","zpool clear -- \"$1\" \"$2\"","emisar","{{ args.pool }}","{{ args.device }}"]}},{"id":"zfs.dataset_list","title":"zfs list","summary":"List all datasets with used + avail + refer + mountpoint.","description":"List all datasets with used + avail + refer + mountpoint.","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[],"examples":[{"title":"Datasets","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-Hp"]}},{"id":"zfs.dataset_rollback","title":"zfs rollback <dataset>@<snap>","summary":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","description":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","kind":"exec","risk":"critical","side_effects":["Dataset reverts to the snapshot's state.","All data written after the snapshot is destroyed.","Intermediate snapshots destroyed.","Running processes with open file handles may break."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}},{"name":"force","type":"boolean","required":false,"default":false,"description":"Destroy intermediate snapshots (zfs rollback -r)."}],"examples":[{"title":"Roll back to a backup","args":{"dataset":"tank/home","force":true,"snap":"pre-disaster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.force }}' = 'true' ]; then zfs rollback -r ''\"$1\"'@'\"$2\"''; else zfs rollback ''\"$1\"'@'\"$2\"''; fi","emisar","{{ args.dataset }}","{{ args.snap }}"]}},{"id":"zfs.pool_iostat","title":"zpool iostat (5s sample)","summary":"Show one 5-second iostat sample per pool.","description":"Show one 5-second iostat sample per pool.","kind":"exec","risk":"low","side_effects":["Reads pool metrics.","Read-only."],"args":[],"examples":[{"title":"iostat sample","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["iostat","-v","5","1"]}},{"id":"zfs.pool_list","title":"zpool list","summary":"List all pools with size + alloc + free + fragmentation.","description":"List all pools with size + alloc + free + fragmentation.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["list","-Hp"]}},{"id":"zfs.pool_status","title":"zpool status -v","summary":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","description":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[{"name":"pool","type":"string","required":false,"default":"","description":"Specific pool (empty = all).","validation":{"pattern":"^([a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63})?$"}}],"examples":[{"title":"All pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then zpool status -v; else zpool status -v \"${1}\"; fi","emisar","{{ args.pool }}"]}},{"id":"zfs.properties","title":"zfs get all <dataset>","summary":"List all properties of one dataset (compression, dedup, atime, quota, etc).","description":"List all properties of one dataset (compression, dedup, atime, quota, etc).","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[{"name":"dataset","type":"string","required":true,"description":"Dataset name.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}}],"examples":[{"title":"Dataset props","args":{"dataset":"tank/data"}}],"search_terms":[],"command":{"binary":"zfs","argv":["get","all","{{ args.dataset }}"]}},{"id":"zfs.scrub_stop","title":"zpool scrub -s <pool>","summary":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","description":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","kind":"exec","risk":"medium","side_effects":["Scrub stops.","Progress lost; next scrub starts from zero.","Any checksum errors found so far remain in the counters."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Cancel scrub on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","-s","{{ args.pool }}"]}},{"id":"zfs.snapshot_destroy","title":"zfs destroy <pool>/<dataset>@<snap>","summary":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","description":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","kind":"exec","risk":"high","side_effects":["Snapshot deleted.","Blocks unique to the snapshot freed.","Restore from this snapshot no longer possible."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}}],"examples":[{"title":"Drop an old snapshot","args":{"dataset":"tank/home","snap":"auto-2026-05-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["destroy","{{ args.dataset }}@{{ args.snap }}"]}},{"id":"zfs.snapshot_list","title":"zfs list -t snapshot","summary":"List all snapshots with used + refer + creation.","description":"List all snapshots with used + refer + creation.","kind":"exec","risk":"low","side_effects":["Reads snapshot metadata.","Read-only."],"args":[],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-t","snapshot","-Hp"]}},{"id":"zfs.start_scrub","title":"zpool scrub <pool>","summary":"Start a scrub on one pool. Re-reads every block and verifies checksums.","description":"Start a scrub on one pool. Re-reads every block and verifies checksums.","kind":"exec","risk":"high","side_effects":["Heavy disk read load for hours-to-days.","Pool stays online; IO latency increases."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Start scrub","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","{{ args.pool }}"]}},{"id":"zfs.take_snapshot","title":"zfs snapshot <dataset>@<name>","summary":"Take an atomic snapshot of one dataset. Copy-on-write, instant.","description":"Take an atomic snapshot of one dataset. Copy-on-write, instant.","kind":"exec","risk":"medium","side_effects":["Snapshot is created; consumes increasing space as live dataset diverges."],"args":[{"name":"dataset","type":"string","required":true,"description":"Source dataset.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}},{"name":"name","type":"string","required":true,"description":"Snapshot name (no @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Manual snapshot","args":{"dataset":"tank/data","name":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["snapshot","{{ args.dataset }}@{{ args.name }}"]}}],"previous_versions":[{"version":"0.1.12","content_hash":"sha256:c617f4727c3e36403574f9e4245901fe89bc966abb96584b74647d9b9c3d10e6","tarball_url":"https://registry.emisar.dev/v1/packs/zfs/0.1.12/c617f4727c3e36403574f9e4245901fe89bc966abb96584b74647d9b9c3d10e6/pack.tar.gz","actions":[{"id":"zfs.arc_stats","title":"/proc/spl/kstat/zfs/arcstats","summary":"Show ARC cache statistics — size, hit ratio, eviction counts.","description":"Show ARC cache statistics — size, hit ratio, eviction counts.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"ARC stats","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/spl/kstat/zfs/arcstats"]}},{"id":"zfs.clear_pool_errors","title":"zpool clear <pool> [device]","summary":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","description":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","kind":"exec","risk":"high","side_effects":["Read, write, checksum error counters reset.","FAULTED devices marked ONLINE if reachable.","Resilvering may start if needed."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"device","type":"string","required":false,"default":"","description":"Specific device (empty for all).","validation":{"pattern":"^([a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127})?$"}}],"examples":[{"title":"Clear all errors on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","zpool clear -- \"$1\" \"$2\"","emisar","{{ args.pool }}","{{ args.device }}"]}},{"id":"zfs.dataset_list","title":"zfs list","summary":"List all datasets with used + avail + refer + mountpoint.","description":"List all datasets with used + avail + refer + mountpoint.","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[],"examples":[{"title":"Datasets","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-Hp"]}},{"id":"zfs.dataset_rollback","title":"zfs rollback <dataset>@<snap>","summary":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","description":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","kind":"exec","risk":"critical","side_effects":["Dataset reverts to the snapshot's state.","All data written after the snapshot is destroyed.","Intermediate snapshots destroyed.","Running processes with open file handles may break."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}},{"name":"force","type":"boolean","required":false,"default":false,"description":"Destroy intermediate snapshots (zfs rollback -r)."}],"examples":[{"title":"Roll back to a backup","args":{"dataset":"tank/home","force":true,"snap":"pre-disaster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.force }}' = 'true' ]; then zfs rollback -r ''\"$1\"'@'\"$2\"''; else zfs rollback ''\"$1\"'@'\"$2\"''; fi","emisar","{{ args.dataset }}","{{ args.snap }}"]}},{"id":"zfs.pool_iostat","title":"zpool iostat (5s sample)","summary":"Show one 5-second iostat sample per pool.","description":"Show one 5-second iostat sample per pool.","kind":"exec","risk":"low","side_effects":["Reads pool metrics.","Read-only."],"args":[],"examples":[{"title":"iostat sample","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["iostat","-v","5","1"]}},{"id":"zfs.pool_list","title":"zpool list","summary":"List all pools with size + alloc + free + fragmentation.","description":"List all pools with size + alloc + free + fragmentation.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["list","-Hp"]}},{"id":"zfs.pool_status","title":"zpool status -v","summary":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","description":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[{"name":"pool","type":"string","required":false,"default":"","description":"Specific pool (empty = all).","validation":{"pattern":"^([a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63})?$"}}],"examples":[{"title":"All pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then zpool status -v; else zpool status -v \"${1}\"; fi","emisar","{{ args.pool }}"]}},{"id":"zfs.properties","title":"zfs get all <dataset>","summary":"List all properties of one dataset (compression, dedup, atime, quota, etc).","description":"List all properties of one dataset (compression, dedup, atime, quota, etc).","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[{"name":"dataset","type":"string","required":true,"description":"Dataset name.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}}],"examples":[{"title":"Dataset props","args":{"dataset":"tank/data"}}],"search_terms":[],"command":{"binary":"zfs","argv":["get","all","{{ args.dataset }}"]}},{"id":"zfs.scrub_stop","title":"zpool scrub -s <pool>","summary":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","description":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","kind":"exec","risk":"medium","side_effects":["Scrub stops.","Progress lost; next scrub starts from zero.","Any checksum errors found so far remain in the counters."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Cancel scrub on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","-s","{{ args.pool }}"]}},{"id":"zfs.snapshot_destroy","title":"zfs destroy <pool>/<dataset>@<snap>","summary":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","description":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","kind":"exec","risk":"high","side_effects":["Snapshot deleted.","Blocks unique to the snapshot freed.","Restore from this snapshot no longer possible."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}}],"examples":[{"title":"Drop an old snapshot","args":{"dataset":"tank/home","snap":"auto-2026-05-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["destroy","{{ args.dataset }}@{{ args.snap }}"]}},{"id":"zfs.snapshot_list","title":"zfs list -t snapshot","summary":"List all snapshots with used + refer + creation.","description":"List all snapshots with used + refer + creation.","kind":"exec","risk":"low","side_effects":["Reads snapshot metadata.","Read-only."],"args":[],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-t","snapshot","-Hp"]}},{"id":"zfs.start_scrub","title":"zpool scrub <pool>","summary":"Start a scrub on one pool. Re-reads every block and verifies checksums.","description":"Start a scrub on one pool. Re-reads every block and verifies checksums.","kind":"exec","risk":"high","side_effects":["Heavy disk read load for hours-to-days.","Pool stays online; IO latency increases."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Start scrub","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","{{ args.pool }}"]}},{"id":"zfs.take_snapshot","title":"zfs snapshot <dataset>@<name>","summary":"Take an atomic snapshot of one dataset. Copy-on-write, instant.","description":"Take an atomic snapshot of one dataset. Copy-on-write, instant.","kind":"exec","risk":"medium","side_effects":["Snapshot is created; consumes increasing space as live dataset diverges."],"args":[{"name":"dataset","type":"string","required":true,"description":"Source dataset.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}},{"name":"name","type":"string","required":true,"description":"Snapshot name (no @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Manual snapshot","args":{"dataset":"tank/data","name":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["snapshot","{{ args.dataset }}@{{ args.name }}"]}}]},{"version":"0.1.11","content_hash":"sha256:092e7bc04f502c47c0e74a3d9b60cc6b0a6993a6491531d40bf70e8cb02e09d3","tarball_url":"https://registry.emisar.dev/v1/packs/zfs/0.1.11/092e7bc04f502c47c0e74a3d9b60cc6b0a6993a6491531d40bf70e8cb02e09d3/pack.tar.gz","actions":[{"id":"zfs.arc_stats","title":"/proc/spl/kstat/zfs/arcstats","summary":"Show ARC cache statistics — size, hit ratio, eviction counts.","description":"Show ARC cache statistics — size, hit ratio, eviction counts.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"ARC stats","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/spl/kstat/zfs/arcstats"]}},{"id":"zfs.clear_pool_errors","title":"zpool clear <pool> [device]","summary":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","description":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","kind":"exec","risk":"high","side_effects":["Read, write, checksum error counters reset.","FAULTED devices marked ONLINE if reachable.","Resilvering may start if needed."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"device","type":"string","required":false,"default":"","description":"Specific device (empty for all).","validation":{"pattern":"^([a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127})?$"}}],"examples":[{"title":"Clear all errors on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","zpool clear -- \"$1\" \"$2\"","emisar","{{ args.pool }}","{{ args.device }}"]}},{"id":"zfs.dataset_list","title":"zfs list","summary":"List all datasets with used + avail + refer + mountpoint.","description":"List all datasets with used + avail + refer + mountpoint.","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[],"examples":[{"title":"Datasets","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-Hp"]}},{"id":"zfs.dataset_rollback","title":"zfs rollback <dataset>@<snap>","summary":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","description":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","kind":"exec","risk":"critical","side_effects":["Dataset reverts to the snapshot's state.","All data written after the snapshot is destroyed.","Intermediate snapshots destroyed.","Running processes with open file handles may break."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}},{"name":"force","type":"boolean","required":false,"default":false,"description":"Destroy intermediate snapshots (zfs rollback -r)."}],"examples":[{"title":"Roll back to a backup","args":{"dataset":"tank/home","force":true,"snap":"pre-disaster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.force }}' = 'true' ]; then zfs rollback -r ''\"$1\"'@'\"$2\"''; else zfs rollback ''\"$1\"'@'\"$2\"''; fi","emisar","{{ args.dataset }}","{{ args.snap }}"]}},{"id":"zfs.pool_iostat","title":"zpool iostat (5s sample)","summary":"Show one 5-second iostat sample per pool.","description":"Show one 5-second iostat sample per pool.","kind":"exec","risk":"low","side_effects":["Reads pool metrics.","Read-only."],"args":[],"examples":[{"title":"iostat sample","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["iostat","-v","5","1"]}},{"id":"zfs.pool_list","title":"zpool list","summary":"List all pools with size + alloc + free + fragmentation.","description":"List all pools with size + alloc + free + fragmentation.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["list","-Hp"]}},{"id":"zfs.pool_status","title":"zpool status -v","summary":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","description":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[{"name":"pool","type":"string","required":false,"default":"","description":"Specific pool (empty = all).","validation":{"pattern":"^([a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63})?$"}}],"examples":[{"title":"All pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then zpool status -v; else zpool status -v \"${1}\"; fi","emisar","{{ args.pool }}"]}},{"id":"zfs.properties","title":"zfs get all <dataset>","summary":"List all properties of one dataset (compression, dedup, atime, quota, etc).","description":"List all properties of one dataset (compression, dedup, atime, quota, etc).","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[{"name":"dataset","type":"string","required":true,"description":"Dataset name.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}}],"examples":[{"title":"Dataset props","args":{"dataset":"tank/data"}}],"search_terms":[],"command":{"binary":"zfs","argv":["get","all","{{ args.dataset }}"]}},{"id":"zfs.scrub_stop","title":"zpool scrub -s <pool>","summary":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","description":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","kind":"exec","risk":"medium","side_effects":["Scrub stops.","Progress lost; next scrub starts from zero.","Any checksum errors found so far remain in the counters."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Cancel scrub on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","-s","{{ args.pool }}"]}},{"id":"zfs.snapshot_destroy","title":"zfs destroy <pool>/<dataset>@<snap>","summary":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","description":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","kind":"exec","risk":"high","side_effects":["Snapshot deleted.","Blocks unique to the snapshot freed.","Restore from this snapshot no longer possible."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}}],"examples":[{"title":"Drop an old snapshot","args":{"dataset":"tank/home","snap":"auto-2026-05-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["destroy","{{ args.dataset }}@{{ args.snap }}"]}},{"id":"zfs.snapshot_list","title":"zfs list -t snapshot","summary":"List all snapshots with used + refer + creation.","description":"List all snapshots with used + refer + creation.","kind":"exec","risk":"low","side_effects":["Reads snapshot metadata.","Read-only."],"args":[],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-t","snapshot","-Hp"]}},{"id":"zfs.start_scrub","title":"zpool scrub <pool>","summary":"Start a scrub on one pool. Re-reads every block and verifies checksums.","description":"Start a scrub on one pool. Re-reads every block and verifies checksums.","kind":"exec","risk":"high","side_effects":["Heavy disk read load for hours-to-days.","Pool stays online; IO latency increases."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Start scrub","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","{{ args.pool }}"]}},{"id":"zfs.take_snapshot","title":"zfs snapshot <dataset>@<name>","summary":"Take an atomic snapshot of one dataset. Copy-on-write, instant.","description":"Take an atomic snapshot of one dataset. Copy-on-write, instant.","kind":"exec","risk":"medium","side_effects":["Snapshot is created; consumes increasing space as live dataset diverges."],"args":[{"name":"dataset","type":"string","required":true,"description":"Source dataset.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}},{"name":"name","type":"string","required":true,"description":"Snapshot name (no @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Manual snapshot","args":{"dataset":"tank/data","name":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["snapshot","{{ args.dataset }}@{{ args.name }}"]}}]},{"version":"0.1.10","content_hash":"sha256:394990da7ec4c93e828a021c2b15fd3d4f0deffe3c904fbb06c312c15db73ebc","tarball_url":"https://registry.emisar.dev/v1/packs/zfs/0.1.10/394990da7ec4c93e828a021c2b15fd3d4f0deffe3c904fbb06c312c15db73ebc/pack.tar.gz","actions":[{"id":"zfs.arc_stats","title":"/proc/spl/kstat/zfs/arcstats","summary":"Show ARC cache statistics — size, hit ratio, eviction counts.","description":"Show ARC cache statistics — size, hit ratio, eviction counts.","kind":"exec","risk":"low","side_effects":["One file read.","Read-only."],"args":[],"examples":[{"title":"ARC stats","args":{}}],"search_terms":[],"command":{"binary":"cat","argv":["/proc/spl/kstat/zfs/arcstats"]}},{"id":"zfs.clear_pool_errors","title":"zpool clear <pool> [device]","summary":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","description":"Clear pool error counters and re-online any FAULTED device that has come back. Use after replacing a failed disk, or after a transient I/O storm cleared. Does NOT touch on-disk data.","kind":"exec","risk":"high","side_effects":["Read, write, checksum error counters reset.","FAULTED devices marked ONLINE if reachable.","Resilvering may start if needed."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}},{"name":"device","type":"string","required":false,"default":"","description":"Specific device (empty for all).","validation":{"pattern":"^([a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127})?$"}}],"examples":[{"title":"Clear all errors on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","zpool clear -- \"$1\" \"$2\"","emisar","{{ args.pool }}","{{ args.device }}"]}},{"id":"zfs.dataset_list","title":"zfs list","summary":"List all datasets with used + avail + refer + mountpoint.","description":"List all datasets with used + avail + refer + mountpoint.","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[],"examples":[{"title":"Datasets","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-Hp"]}},{"id":"zfs.dataset_rollback","title":"zfs rollback <dataset>@<snap>","summary":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","description":"Roll a dataset back to an earlier snapshot. ALL changes after the snapshot are PERMANENTLY discarded. Intermediate snapshots between current and target are also destroyed (require -r flag). Use only after confirming current data is salvageable from elsewhere or the loss is acceptable.","kind":"exec","risk":"critical","side_effects":["Dataset reverts to the snapshot's state.","All data written after the snapshot is destroyed.","Intermediate snapshots destroyed.","Running processes with open file handles may break."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}},{"name":"force","type":"boolean","required":false,"default":false,"description":"Destroy intermediate snapshots (zfs rollback -r)."}],"examples":[{"title":"Roll back to a backup","args":{"dataset":"tank/home","force":true,"snap":"pre-disaster"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ '{{ args.force }}' = 'true' ]; then zfs rollback -r ''\"$1\"'@'\"$2\"''; else zfs rollback ''\"$1\"'@'\"$2\"''; fi","emisar","{{ args.dataset }}","{{ args.snap }}"]}},{"id":"zfs.pool_iostat","title":"zpool iostat (5s sample)","summary":"Show one 5-second iostat sample per pool.","description":"Show one 5-second iostat sample per pool.","kind":"exec","risk":"low","side_effects":["Reads pool metrics.","Read-only."],"args":[],"examples":[{"title":"iostat sample","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["iostat","-v","5","1"]}},{"id":"zfs.pool_list","title":"zpool list","summary":"List all pools with size + alloc + free + fragmentation.","description":"List all pools with size + alloc + free + fragmentation.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[],"examples":[{"title":"Pools","args":{}}],"search_terms":[],"command":{"binary":"zpool","argv":["list","-Hp"]}},{"id":"zfs.pool_status","title":"zpool status -v","summary":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","description":"Show per-pool vdev tree, scrub state, errors. Use to debug DEGRADED pools.","kind":"exec","risk":"low","side_effects":["Reads pool metadata.","Read-only."],"args":[{"name":"pool","type":"string","required":false,"default":"","description":"Specific pool (empty = all).","validation":{"pattern":"^([a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63})?$"}}],"examples":[{"title":"All pools","args":{}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","if [ -z \"${1}\" ]; then zpool status -v; else zpool status -v \"${1}\"; fi","emisar","{{ args.pool }}"]}},{"id":"zfs.properties","title":"zfs get all <dataset>","summary":"List all properties of one dataset (compression, dedup, atime, quota, etc).","description":"List all properties of one dataset (compression, dedup, atime, quota, etc).","kind":"exec","risk":"low","side_effects":["Reads dataset metadata.","Read-only."],"args":[{"name":"dataset","type":"string","required":true,"description":"Dataset name.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}}],"examples":[{"title":"Dataset props","args":{"dataset":"tank/data"}}],"search_terms":[],"command":{"binary":"zfs","argv":["get","all","{{ args.dataset }}"]}},{"id":"zfs.scrub_stop","title":"zpool scrub -s <pool>","summary":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","description":"Stop an in-progress scrub. Use when scrub is impacting workload and the verification can wait for a maintenance window.","kind":"exec","risk":"medium","side_effects":["Scrub stops.","Progress lost; next scrub starts from zero.","Any checksum errors found so far remain in the counters."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_][a-zA-Z0-9_\\-]{0,63}$"}}],"examples":[{"title":"Cancel scrub on tank","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","-s","{{ args.pool }}"]}},{"id":"zfs.snapshot_destroy","title":"zfs destroy <pool>/<dataset>@<snap>","summary":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","description":"Delete one ZFS snapshot. Reclaims the snapshot-exclusive blocks immediately. Irreversible. Confirm the snapshot is not the only thing protecting against a recent ransomware/oops event before destroying.","kind":"exec","risk":"high","side_effects":["Snapshot deleted.","Blocks unique to the snapshot freed.","Restore from this snapshot no longer possible."],"args":[{"name":"dataset","type":"string","required":true,"description":"Full dataset path.","validation":{"pattern":"^[a-zA-Z0-9_/.][a-zA-Z0-9_/.\\-]{0,127}$"}},{"name":"snap","type":"string","required":true,"description":"Snapshot name (after the @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-:]{1,64}$"}}],"examples":[{"title":"Drop an old snapshot","args":{"dataset":"tank/home","snap":"auto-2026-05-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["destroy","{{ args.dataset }}@{{ args.snap }}"]}},{"id":"zfs.snapshot_list","title":"zfs list -t snapshot","summary":"List all snapshots with used + refer + creation.","description":"List all snapshots with used + refer + creation.","kind":"exec","risk":"low","side_effects":["Reads snapshot metadata.","Read-only."],"args":[],"examples":[{"title":"Snapshots","args":{}}],"search_terms":[],"command":{"binary":"zfs","argv":["list","-t","snapshot","-Hp"]}},{"id":"zfs.start_scrub","title":"zpool scrub <pool>","summary":"Starts a scrub on one pool. Re-reads every block and verifies checksums.","description":"Starts a scrub on one pool. Re-reads every block and verifies checksums.","kind":"exec","risk":"high","side_effects":["Heavy disk read load for hours-to-days.","Pool stays online; IO latency increases."],"args":[{"name":"pool","type":"string","required":true,"description":"Pool name.","validation":{"pattern":"^[a-zA-Z0-9_.][a-zA-Z0-9_.\\-]{0,63}$"}}],"examples":[{"title":"Start scrub","args":{"pool":"tank"}}],"search_terms":[],"command":{"binary":"zpool","argv":["scrub","{{ args.pool }}"]}},{"id":"zfs.take_snapshot","title":"zfs snapshot <dataset>@<name>","summary":"Takes an atomic snapshot of one dataset. Copy-on-write, instant.","description":"Takes an atomic snapshot of one dataset. Copy-on-write, instant.","kind":"exec","risk":"medium","side_effects":["Snapshot is created; consumes increasing space as live dataset diverges."],"args":[{"name":"dataset","type":"string","required":true,"description":"Source dataset.","validation":{"pattern":"^[a-zA-Z0-9_./][a-zA-Z0-9_./\\-]{0,127}$"}},{"name":"name","type":"string","required":true,"description":"Snapshot name (no @).","validation":{"pattern":"^[a-zA-Z0-9_.\\-]{1,64}$"}}],"examples":[{"title":"Manual snapshot","args":{"dataset":"tank/data","name":"pre-migration-2026-06-01"}}],"search_terms":[],"command":{"binary":"zfs","argv":["snapshot","{{ args.dataset }}@{{ args.name }}"]}}]}],"retired_below":"0.1.9"},{"id":"zookeeper","name":"ZooKeeper operations","version":"0.1.10","description":"Cluster + 4lw command + watch + session introspection. Read-only. Set ZK_SERVERS env var (host:port,host:port,…). All four-letter words need to be in zoo.cfg's `4lw.commands.whitelist`.","vendor":"emisar","homepage":"https://emisar.dev/packs/zookeeper","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/zookeeper","content_hash":"sha256:b237b6575151fb891f136236f6e1eb39f325f82448c8c9f0832213608caaab51","tarball_url":"https://registry.emisar.dev/v1/packs/zookeeper/0.1.10/b237b6575151fb891f136236f6e1eb39f325f82448c8c9f0832213608caaab51/pack.tar.gz","requires":{"os":["linux"],"binaries":["nc"]},"detect":{"binaries":["zkServer.sh","zkCli.sh"],"processes":["QuorumPeerMain"],"ports":[2181]},"setup":{"summary":"No credentials and no env vars. Each action targets a ZooKeeper node by a required server argument (host:port) and probes it with a four-letter word over a plain nc TCP connection.","notes":["Targeting is per-call, not via env: pass server=host:port to every action (the ZK_SERVERS list in the description is operator shorthand, not read by any action).","The 4lw commands (srvr, stat, conf, cons, wchs, ruok, mntr, envi) only work if each is in the node's zoo.cfg 4lw.commands.whitelist.","The runner host must have plain TCP reach to the client port (default 2181); 4lw is unauthenticated, so restrict it at the network layer."],"verify":"zk.ruok"},"actions":[{"id":"zk.conf","title":"conf (server config)","summary":"Show the server's effective configuration via the `conf` four-letter word. The output is a fixed, bounded property list (client ports, data/log dirs and sizes, tick + session timeouts, serverId, and on quorum members the election/quorum ports and membership) — it discloses paths and topology; stock ZooKeeper does not dump zoo.cfg or arbitrary properties here, so auth material like `superDigest` never appears.","description":"Show the server's effective configuration via the `conf` four-letter word. The output is a fixed, bounded property list (client ports, data/log dirs and sizes, tick + session timeouts, serverId, and on quorum members the election/quorum ports and membership) — it discloses paths and topology; stock ZooKeeper does not dump zoo.cfg or arbitrary properties here, so auth material like `superDigest` never appears.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only; discloses paths and topology — no secret values."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Conf","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo conf | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.cons","title":"cons (all connections)","summary":"List all client connections + their session + per-session stats.","description":"List all client connections + their session + per-session stats.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Connections","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo cons | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.envi","title":"envi (server env)","summary":"Show the server's JVM + OS environment via the `envi` four-letter word. The output is a fixed, bounded property list (zookeeper.version, host.name, java.version/vendor/home, class + library paths, java.io.tmpdir, os.*, user.name/home/dir, JVM memory totals) — it discloses install paths, usernames, and topology; stock ZooKeeper does not print arbitrary system properties or injected secret values here.","description":"Show the server's JVM + OS environment via the `envi` four-letter word. The output is a fixed, bounded property list (zookeeper.version, host.name, java.version/vendor/home, class + library paths, java.io.tmpdir, os.*, user.name/home/dir, JVM memory totals) — it discloses install paths, usernames, and topology; stock ZooKeeper does not print arbitrary system properties or injected secret values here.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only; discloses install paths, usernames, and topology — no secret values."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Server env","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo envi | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.mntr","title":"mntr (monitoring metrics)","summary":"Show per-server metrics in a metrics-friendly format.","description":"Show per-server metrics in a metrics-friendly format.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Metrics","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo mntr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.ruok","title":"ruok (health probe)","summary":"Check server health — returns 'imok' if server is serving.","description":"Check server health — returns 'imok' if server is serving.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Are you OK?","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo ruok | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.srvr","title":"srvr (server stats)","summary":"Show server version, latency, packets, mode (leader/follower/standalone).","description":"Show server version, latency, packets, mode (leader/follower/standalone).","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"One server","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo srvr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.stat","title":"stat (server + per-conn stats)","summary":"Show server + per-connection latency, packet counts.","description":"Show server + per-connection latency, packet counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"stat","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo stat | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.wchs","title":"wchs (watch summary)","summary":"Show active watch counts.","description":"Show active watch counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Watches","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo wchs | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}}],"previous_versions":[{"version":"0.1.9","content_hash":"sha256:e2f58b8d1aee37ee452b0ce6d1e65f19401ba413add67ba4170e76d9bff95658","tarball_url":"https://registry.emisar.dev/v1/packs/zookeeper/0.1.9/e2f58b8d1aee37ee452b0ce6d1e65f19401ba413add67ba4170e76d9bff95658/pack.tar.gz","actions":[{"id":"zk.conf","title":"conf (server config)","summary":"Show the server's effective configuration via the `conf` four-letter word. The output is a fixed, bounded property list (client ports, data/log dirs and sizes, tick + session timeouts, serverId, and on quorum members the election/quorum ports and membership) — it discloses paths and topology; stock ZooKeeper does not dump zoo.cfg or arbitrary properties here, so auth material like `superDigest` never appears.","description":"Show the server's effective configuration via the `conf` four-letter word. The output is a fixed, bounded property list (client ports, data/log dirs and sizes, tick + session timeouts, serverId, and on quorum members the election/quorum ports and membership) — it discloses paths and topology; stock ZooKeeper does not dump zoo.cfg or arbitrary properties here, so auth material like `superDigest` never appears.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only; discloses paths and topology — no secret values."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Conf","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo conf | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.cons","title":"cons (all connections)","summary":"List all client connections + their session + per-session stats.","description":"List all client connections + their session + per-session stats.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Connections","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo cons | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.envi","title":"envi (server env)","summary":"Show the server's JVM + OS environment via the `envi` four-letter word. The output is a fixed, bounded property list (zookeeper.version, host.name, java.version/vendor/home, class + library paths, java.io.tmpdir, os.*, user.name/home/dir, JVM memory totals) — it discloses install paths, usernames, and topology; stock ZooKeeper does not print arbitrary system properties or injected secret values here.","description":"Show the server's JVM + OS environment via the `envi` four-letter word. The output is a fixed, bounded property list (zookeeper.version, host.name, java.version/vendor/home, class + library paths, java.io.tmpdir, os.*, user.name/home/dir, JVM memory totals) — it discloses install paths, usernames, and topology; stock ZooKeeper does not print arbitrary system properties or injected secret values here.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only; discloses install paths, usernames, and topology — no secret values."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Server env","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo envi | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.mntr","title":"mntr (monitoring metrics)","summary":"Show per-server metrics in a metrics-friendly format.","description":"Show per-server metrics in a metrics-friendly format.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Metrics","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo mntr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.ruok","title":"ruok (health probe)","summary":"Check server health — returns 'imok' if server is serving.","description":"Check server health — returns 'imok' if server is serving.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Are you OK?","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo ruok | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.srvr","title":"srvr (server stats)","summary":"Show server version, latency, packets, mode (leader/follower/standalone).","description":"Show server version, latency, packets, mode (leader/follower/standalone).","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"One server","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo srvr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.stat","title":"stat (server + per-conn stats)","summary":"Show server + per-connection latency, packet counts.","description":"Show server + per-connection latency, packet counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"stat","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo stat | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.wchs","title":"wchs (watch summary)","summary":"Show active watch counts.","description":"Show active watch counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Watches","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo wchs | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}}]},{"version":"0.1.8","content_hash":"sha256:f55ab3a726debd3282946a705d95ed015e5a7d7a13df1d6964287185dee31e5c","tarball_url":"https://registry.emisar.dev/v1/packs/zookeeper/0.1.8/f55ab3a726debd3282946a705d95ed015e5a7d7a13df1d6964287185dee31e5c/pack.tar.gz","actions":[{"id":"zk.conf","title":"conf (server config)","summary":"Show the server's effective configuration via the `conf` four-letter word. The output is a fixed, bounded property list (client ports, data/log dirs and sizes, tick + session timeouts, serverId, and on quorum members the election/quorum ports and membership) — it discloses paths and topology; stock ZooKeeper does not dump zoo.cfg or arbitrary properties here, so auth material like `superDigest` never appears.","description":"Show the server's effective configuration via the `conf` four-letter word. The output is a fixed, bounded property list (client ports, data/log dirs and sizes, tick + session timeouts, serverId, and on quorum members the election/quorum ports and membership) — it discloses paths and topology; stock ZooKeeper does not dump zoo.cfg or arbitrary properties here, so auth material like `superDigest` never appears.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only; discloses paths and topology — no secret values."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Conf","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo conf | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.cons","title":"cons (all connections)","summary":"List all client connections + their session + per-session stats.","description":"List all client connections + their session + per-session stats.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Connections","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo cons | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.envi","title":"envi (server env)","summary":"Show the server's JVM + OS environment via the `envi` four-letter word. The output is a fixed, bounded property list (zookeeper.version, host.name, java.version/vendor/home, class + library paths, java.io.tmpdir, os.*, user.name/home/dir, JVM memory totals) — it discloses install paths, usernames, and topology; stock ZooKeeper does not print arbitrary system properties or injected secret values here.","description":"Show the server's JVM + OS environment via the `envi` four-letter word. The output is a fixed, bounded property list (zookeeper.version, host.name, java.version/vendor/home, class + library paths, java.io.tmpdir, os.*, user.name/home/dir, JVM memory totals) — it discloses install paths, usernames, and topology; stock ZooKeeper does not print arbitrary system properties or injected secret values here.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only; discloses install paths, usernames, and topology — no secret values."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Server env","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo envi | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.mntr","title":"mntr (monitoring metrics)","summary":"Show per-server metrics in a metrics-friendly format.","description":"Show per-server metrics in a metrics-friendly format.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Metrics","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo mntr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.ruok","title":"ruok (health probe)","summary":"Check server health — returns 'imok' if server is serving.","description":"Check server health — returns 'imok' if server is serving.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Are you OK?","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo ruok | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.srvr","title":"srvr (server stats)","summary":"Show server version, latency, packets, mode (leader/follower/standalone).","description":"Show server version, latency, packets, mode (leader/follower/standalone).","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"One server","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo srvr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.stat","title":"stat (server + per-conn stats)","summary":"Show server + per-connection latency, packet counts.","description":"Show server + per-connection latency, packet counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"stat","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo stat | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.wchs","title":"wchs (watch summary)","summary":"Show active watch counts.","description":"Show active watch counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Watches","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo wchs | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}}]},{"version":"0.1.6","content_hash":"sha256:564bbc3582e773c1a4b8e4da190432a1ea3ab57526e4a02f8769aafdd9c3e3e7","tarball_url":"https://registry.emisar.dev/v1/packs/zookeeper/0.1.6/564bbc3582e773c1a4b8e4da190432a1ea3ab57526e4a02f8769aafdd9c3e3e7/pack.tar.gz","actions":[{"id":"zk.conf","title":"conf (server config)","summary":"Show the server's effective configuration.","description":"Show the server's effective configuration.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Conf","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo conf | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.cons","title":"cons (all connections)","summary":"List all client connections + their session + per-session stats.","description":"List all client connections + their session + per-session stats.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Connections","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo cons | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.envi","title":"envi (server env)","summary":"Show the server's JVM + OS environment via the `envi` four-letter word.","description":"Show the server's JVM + OS environment via the `envi` four-letter word. This deliberately dumps the node's environment — JVM system properties and OS/user details (java.class.path, java.io.tmpdir, java.home, user.name, user.home, user.dir, os.*) — which discloses install paths, usernames, and topology, and on some builds carries values injected via system properties. The runner's redaction is a fail-closed backstop, not a guarantee — it is pattern-bound and can miss a bespoke secret whose name and value match no rule.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only, but exposes the server's full JVM/OS environment (may include secrets)."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Server env","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo envi | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.mntr","title":"mntr (monitoring metrics)","summary":"Show per-server metrics in a metrics-friendly format.","description":"Show per-server metrics in a metrics-friendly format.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Metrics","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo mntr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.ruok","title":"ruok (health probe)","summary":"Check server health — returns 'imok' if server is serving.","description":"Check server health — returns 'imok' if server is serving.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Are you OK?","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo ruok | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.srvr","title":"srvr (server stats)","summary":"Show server version, latency, packets, mode (leader/follower/standalone).","description":"Show server version, latency, packets, mode (leader/follower/standalone).","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"One server","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo srvr | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.stat","title":"stat (server + per-conn stats)","summary":"Show server + per-connection latency, packet counts.","description":"Show server + per-connection latency, packet counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"stat","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo stat | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}},{"id":"zk.wchs","title":"wchs (watch summary)","summary":"Show active watch counts.","description":"Show active watch counts.","kind":"exec","risk":"low","side_effects":["One 4lw command.","Read-only."],"args":[{"name":"server","type":"string","required":true,"description":"host:port.","validation":{"pattern":"^[a-zA-Z0-9][a-zA-Z0-9.\\-]{0,254}:[0-9]{1,5}$"}}],"examples":[{"title":"Watches","args":{"server":"zk1:2181"}}],"search_terms":[],"command":{"binary":"/bin/sh","argv":["-c","S=''\"$1\"''; echo wchs | nc -w 5 ${S%:*} ${S##*:}","emisar","{{ args.server }}"]}}]}]},{"id":"zot","name":"zot OCI registry","version":"0.1.9","description":"Read-only inspection of a zot OCI registry over its HTTP API: the OCI distribution endpoints (version check, catalog, tags, manifests) plus the zot extensions — registry config/health (mgmt), Prometheus metrics, and a GraphQL search query that returns per-repo size and a newest-image vulnerability summary. Optional basic-auth credentials are streamed over curl stdin; many zot deployments allow anonymous read.","vendor":"emisar","homepage":"https://emisar.dev/packs/zot","source_url":"https://github.com/andrewdryga/emisar/tree/main/packs/zot","content_hash":"sha256:8384fdcb6b73ca4e8500e5f86c1c7d96ee1397bc91b2361bd47654c1e2228ba9","tarball_url":"https://registry.emisar.dev/v1/packs/zot/0.1.9/8384fdcb6b73ca4e8500e5f86c1c7d96ee1397bc91b2361bd47654c1e2228ba9/pack.tar.gz","requires":{"os":["linux"],"binaries":["curl"]},"detect":{"binaries":[],"processes":["zot"],"ports":[5000]},"setup":{"summary":"Every action calls the zot HTTP API at `$ZOT_URL` via curl on the runner host. Optional basic-auth credentials \"user:password\" are read from `$ZOT_BASICAUTH`, base64-encoded, and sent as an Authorization header over curl stdin, so they never appear in the process arguments or the audit log.","env":[{"name":"ZOT_URL","description":"Base URL of the zot registry — scheme, host, and port. Each action appends its path (e.g. /v2/, /v2/_catalog).","default":"http://127.0.0.1:5000","example":"http://zot:5000"},{"name":"ZOT_BASICAUTH","description":"Optional user:password for registries that require auth; base64-encoded and sent as an Authorization header over curl stdin, never argv. Leave unset for anonymous-read registries."}],"notes":["Any of `ZOT_URL` / `ZOT_BASICAUTH` you set must also be allowlisted in the runner's `execution.inherit_env` — the action env is scrubbed to PATH/LANG/LC_ALL/TERM by default, so an env present on the host but not allowlisted is silently dropped (the action falls back to its local default or fails auth).","Every action is read-only: GET, plus POST only to the read-only search GraphQL extension. Push/delete of manifests and blobs, and userprefs writes, are deliberately excluded.","The search/mgmt/metrics extensions require the full (extended) zot build — search/ui/mgmt are on by default; metrics must be enabled in config.","mgmt and metrics typically require auth and are denied to anonymous clients; set `ZOT_BASICAUTH` for those."],"verify":"zot.v2_base"},"actions":[{"id":"zot.catalog","title":"GET /v2/_catalog","summary":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","description":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_catalog endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"List repositories","args":{}}],"search_terms":["list images"]},{"id":"zot.manifest","title":"GET /v2/{repo}/manifests/{reference}","summary":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","description":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/manifests/{reference} endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}},{"name":"reference","type":"string","required":true,"description":"A tag or a digest (e.g. latest or sha256:...).","validation":{"pattern":"^[A-Za-z0-9._:@-]{1,256}$"}}],"examples":[{"title":"Manifest for library/alpine:latest","args":{"reference":"latest","repo":"library/alpine"}}],"search_terms":[]},{"id":"zot.metrics","title":"GET /metrics","summary":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","description":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /metrics endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Scrape Prometheus metrics","args":{}}],"search_terms":[]},{"id":"zot.mgmt","title":"GET /v2/_zot/ext/mgmt","summary":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","description":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_zot/ext/mgmt endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Read registry config and health","args":{}}],"search_terms":[]},{"id":"zot.search","title":"POST /v2/_zot/ext/search (repo inventory + vuln summary)","summary":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","description":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the zot /v2/_zot/ext/search GraphQL endpoint.","Read-only — the query only reads; it never pushes, deletes, or mutates."],"args":[],"examples":[{"title":"Repo inventory with size and newest-image vuln summary","args":{}}],"search_terms":["cve"]},{"id":"zot.tags","title":"GET /v2/{repo}/tags/list","summary":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","description":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/tags/list endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}}],"examples":[{"title":"Tags for library/alpine","args":{"repo":"library/alpine"}}],"search_terms":["image versions"]},{"id":"zot.v2_base","title":"GET /v2/","summary":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","description":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/ endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Base/version check","args":{}}],"search_terms":["registry down","registry unreachable"]}],"previous_versions":[{"version":"0.1.8","content_hash":"sha256:68ae98c04f88cd8c28f68b4549692a88bbb4fda596a787e5c2cadf8aae8c213f","tarball_url":"https://registry.emisar.dev/v1/packs/zot/0.1.8/68ae98c04f88cd8c28f68b4549692a88bbb4fda596a787e5c2cadf8aae8c213f/pack.tar.gz","actions":[{"id":"zot.catalog","title":"GET /v2/_catalog","summary":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","description":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_catalog endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"List repositories","args":{}}],"search_terms":["list images"]},{"id":"zot.manifest","title":"GET /v2/{repo}/manifests/{reference}","summary":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","description":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/manifests/{reference} endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}},{"name":"reference","type":"string","required":true,"description":"A tag or a digest (e.g. latest or sha256:...).","validation":{"pattern":"^[A-Za-z0-9._:@-]{1,256}$"}}],"examples":[{"title":"Manifest for library/alpine:latest","args":{"reference":"latest","repo":"library/alpine"}}],"search_terms":[]},{"id":"zot.metrics","title":"GET /metrics","summary":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","description":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /metrics endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Scrape Prometheus metrics","args":{}}],"search_terms":[]},{"id":"zot.mgmt","title":"GET /v2/_zot/ext/mgmt","summary":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","description":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_zot/ext/mgmt endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Read registry config and health","args":{}}],"search_terms":[]},{"id":"zot.search","title":"POST /v2/_zot/ext/search (repo inventory + vuln summary)","summary":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","description":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the zot /v2/_zot/ext/search GraphQL endpoint.","Read-only — the query only reads; it never pushes, deletes, or mutates."],"args":[],"examples":[{"title":"Repo inventory with size and newest-image vuln summary","args":{}}],"search_terms":["cve"]},{"id":"zot.tags","title":"GET /v2/{repo}/tags/list","summary":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","description":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/tags/list endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}}],"examples":[{"title":"Tags for library/alpine","args":{"repo":"library/alpine"}}],"search_terms":["image versions"]},{"id":"zot.v2_base","title":"GET /v2/","summary":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","description":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/ endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Base/version check","args":{}}],"search_terms":["registry down","registry unreachable"]}]},{"version":"0.1.6","content_hash":"sha256:5e61db75bcb32003546fa3d7ef1e76fe5955db744a3cfad610d90fd5e50b7824","tarball_url":"https://registry.emisar.dev/v1/packs/zot/0.1.6/5e61db75bcb32003546fa3d7ef1e76fe5955db744a3cfad610d90fd5e50b7824/pack.tar.gz","actions":[{"id":"zot.catalog","title":"GET /v2/_catalog","summary":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","description":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_catalog endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"List repositories","args":{}}],"search_terms":["list images"]},{"id":"zot.manifest","title":"GET /v2/{repo}/manifests/{reference}","summary":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","description":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/manifests/{reference} endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}},{"name":"reference","type":"string","required":true,"description":"A tag or a digest (e.g. latest or sha256:...).","validation":{"pattern":"^[A-Za-z0-9._:@-]{1,256}$"}}],"examples":[{"title":"Manifest for library/alpine:latest","args":{"reference":"latest","repo":"library/alpine"}}],"search_terms":[]},{"id":"zot.metrics","title":"GET /metrics","summary":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","description":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /metrics endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Scrape Prometheus metrics","args":{}}],"search_terms":[]},{"id":"zot.mgmt","title":"GET /v2/_zot/ext/mgmt","summary":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","description":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_zot/ext/mgmt endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Read registry config and health","args":{}}],"search_terms":[]},{"id":"zot.search","title":"POST /v2/_zot/ext/search (repo inventory + vuln summary)","summary":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","description":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the zot /v2/_zot/ext/search GraphQL endpoint.","Read-only — the query only reads; it never pushes, deletes, or mutates."],"args":[],"examples":[{"title":"Repo inventory with size and newest-image vuln summary","args":{}}],"search_terms":["cve"]},{"id":"zot.tags","title":"GET /v2/{repo}/tags/list","summary":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","description":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/tags/list endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}}],"examples":[{"title":"Tags for library/alpine","args":{"repo":"library/alpine"}}],"search_terms":["image versions"]},{"id":"zot.v2_base","title":"GET /v2/","summary":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","description":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/ endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Base/version check","args":{}}],"search_terms":["registry down","registry unreachable"]}]},{"version":"0.1.5","content_hash":"sha256:5a86565b691716316a28cc2e1c3bd47d4e1b2cd05da241c07ff223f1f4e0c15b","tarball_url":"https://registry.emisar.dev/v1/packs/zot/0.1.5/5a86565b691716316a28cc2e1c3bd47d4e1b2cd05da241c07ff223f1f4e0c15b/pack.tar.gz","actions":[{"id":"zot.catalog","title":"GET /v2/_catalog","summary":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","description":"List the repositories in the registry. Large registries paginate via the ?n=<count>&last=<repo> query parameters; this returns the first page. Use to inventory what is stored. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_catalog endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"List repositories","args":{}}],"search_terms":["list images"]},{"id":"zot.manifest","title":"GET /v2/{repo}/manifests/{reference}","summary":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","description":"Read the image manifest for a repository at a given reference (a tag or a digest). Returns the layer/config descriptors and annotations for that image. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/manifests/{reference} endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}},{"name":"reference","type":"string","required":true,"description":"A tag or a digest (e.g. latest or sha256:...).","validation":{"pattern":"^[A-Za-z0-9._:@-]{1,256}$"}}],"examples":[{"title":"Manifest for library/alpine:latest","args":{"reference":"latest","repo":"library/alpine"}}],"search_terms":[]},{"id":"zot.metrics","title":"GET /metrics","summary":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","description":"Show Prometheus-format metrics for the registry via the zot metrics extension — request counts, storage, and runtime gauges. Requires the full (extended) build with the metrics extension enabled in config, and typically auth (set ZOT_BASICAUTH). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /metrics endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Scrape Prometheus metrics","args":{}}],"search_terms":[]},{"id":"zot.mgmt","title":"GET /v2/_zot/ext/mgmt","summary":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","description":"Show registry configuration and health via the zot mgmt extension — the active config (extensions enabled, storage settings) and a health summary. The mgmt extension is on by default in the full build but requires auth and is denied to anonymous clients, so set ZOT_BASICAUTH. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/_zot/ext/mgmt endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Read registry config and health","args":{}}],"search_terms":[]},{"id":"zot.search","title":"POST /v2/_zot/ext/search (repo inventory + vuln summary)","summary":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","description":"List repository inventory with per-repo storage size and a newest-image vulnerability summary, via the zot search GraphQL extension. This is how you get per-repo storage size + CVE summary — zot has no plain storage-usage endpoint, and garbage collection is not inspectable over HTTP. The GraphQL query is read-only (a RepoListWithNewestImage read). Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP POST to the zot /v2/_zot/ext/search GraphQL endpoint.","Read-only — the query only reads; it never pushes, deletes, or mutates."],"args":[],"examples":[{"title":"Repo inventory with size and newest-image vuln summary","args":{}}],"search_terms":["cve"]},{"id":"zot.tags","title":"GET /v2/{repo}/tags/list","summary":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","description":"List the tags available for a single repository. Use after the catalog to see which versions of an image are published. Read-only.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/{repo}/tags/list endpoint.","Read-only — never pushes or deletes."],"args":[{"name":"repo","type":"string","required":true,"description":"Repository name (may include a namespace path).","validation":{"pattern":"^[a-z0-9._/-]{1,256}$"}}],"examples":[{"title":"Tags for library/alpine","args":{"repo":"library/alpine"}}],"search_terms":["image versions"]},{"id":"zot.v2_base","title":"GET /v2/","summary":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","description":"Check the OCI distribution base endpoint. A 200 confirms the registry is up and speaking the v2 API, and the response advertises the supported distribution-spec version. Use as a reachability/version check.","kind":"script","risk":"low","side_effects":["One read-only HTTP GET to the zot /v2/ endpoint.","Read-only — never pushes or deletes."],"args":[],"examples":[{"title":"Base/version check","args":{}}],"search_terms":["registry down","registry unreachable"]}]}]}]}
