terraform-plugin/skills/tfc-list-runs/SKILL.md
List Terraform Cloud workspace runs filtered by status or date. Use when reviewing run history, finding failed runs, or auditing infra changes. Requires TFE_TOKEN.
npx skillsauth add laurigates/claude-plugins tfc-list-runsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
List and filter runs from Terraform Cloud workspaces with formatted output.
| Use this skill when... | Use a sibling instead when... |
|---|---|
| Listing recent runs for an arbitrary TFC workspace by ID | Inspecting a single known run ID for status (tfc-run-status) |
| Filtering runs by status, operation, or source across an org | Reading plan/apply log content for a run (tfc-run-logs) |
| Searching runs by commit SHA or VCS user | Analyzing structured plan JSON for resource changes (tfc-plan-json) |
| Auditing run history across many TFC workspaces | Listing runs for the known Forum Virium workspaces (tfc-workspace-runs) |
export TFE_TOKEN="your-api-token" # User or team token
export TFE_ADDRESS="app.terraform.io" # Optional
#!/bin/bash
set -euo pipefail
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
BASE_URL="https://${TFE_ADDRESS:-app.terraform.io}/api/v2"
WORKSPACE_ID="${1:?Usage: $0 <workspace-id> [limit]}"
LIMIT="${2:-10}"
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?page[size]=$LIMIT" | \
jq -r '.data[] | [
.id,
.attributes.status,
.attributes."created-at"[0:19],
(.attributes.message // "No message")[0:50]
] | @tsv' | \
column -t -s $'\t'
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
BASE_URL="https://${TFE_ADDRESS:-app.terraform.io}/api/v2"
ORG="ForumViriumHelsinki"
WORKSPACE="infrastructure-gcp"
# Get workspace ID first
WS_ID=$(curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/organizations/$ORG/workspaces/$WORKSPACE" | \
jq -r '.data.id')
# List runs
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WS_ID/runs?page[size]=10" | \
jq -r '.data[] | "\(.id) | \(.attributes.status) | \(.attributes."created-at"[0:19]) | \(.attributes.message // "No message")"'
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
BASE_URL="https://${TFE_ADDRESS:-app.terraform.io}/api/v2"
WORKSPACE_ID="ws-abc123"
# Filter by single status
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?filter[status]=errored" | \
jq -r '.data[] | "\(.id) | \(.attributes.status) | \(.attributes."created-at")"'
# Filter by multiple statuses
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?filter[status]=errored,canceled" | \
jq -r '.data[] | "\(.id) | \(.attributes.status)"'
# Non-final runs (in progress)
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?filter[status_group]=non_final"
# Final runs (completed)
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?filter[status_group]=final"
# Discardable runs
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?filter[status_group]=discardable"
By default, plan-only runs are excluded. To include them:
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?filter[operation]=plan_and_apply,plan_only,save_plan,refresh_only,destroy"
TOKEN="${TFE_TOKEN:?TFE_TOKEN not set}"
BASE_URL="https://${TFE_ADDRESS:-app.terraform.io}/api/v2"
ORG="ForumViriumHelsinki"
# All runs in org (limited info, no total count)
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/organizations/$ORG/runs?page[size]=20" | \
jq -r '.data[] | "\(.id) | \(.attributes.status)"'
# Filter by workspace names
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/organizations/$ORG/runs?filter[workspace_names]=infrastructure-gcp,infrastructure-github"
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?page[size]=10&include=plan" | \
jq -r '
["RUN_ID", "STATUS", "ADD", "CHG", "DEL", "CREATED"],
(.data[] | [
.id,
.attributes.status,
(.relationships.plan.data.id as $pid |
(.included[] | select(.id == $pid) | .attributes."resource-additions" // 0)),
(.relationships.plan.data.id as $pid |
(.included[] | select(.id == $pid) | .attributes."resource-changes" // 0)),
(.relationships.plan.data.id as $pid |
(.included[] | select(.id == $pid) | .attributes."resource-destructions" // 0)),
.attributes."created-at"[0:19]
]) | @tsv' | column -t
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?page[size]=5" | \
jq '[.data[] | {
id: .id,
status: .attributes.status,
created: .attributes."created-at",
message: .attributes.message,
has_changes: .attributes."has-changes",
auto_apply: .attributes."auto-apply"
}]'
| Parameter | Description | Example Values |
|-----------|-------------|----------------|
| filter[status] | Run status | applied, errored, planned, canceled |
| filter[status_group] | Status group | non_final, final, discardable |
| filter[operation] | Operation type | plan_and_apply, plan_only, destroy |
| filter[source] | Run source | tfe-api, tfe-ui, tfe-configuration-version |
| filter[timeframe] | Time period | 2024, year, month |
| search[user] | VCS username | Username string |
| search[commit] | Commit SHA | SHA string |
| search[basic] | Combined search | Search term |
Final States: applied, planned_and_finished, discarded, errored, canceled, force_canceled, policy_soft_failed
Non-Final States: pending, planning, planned, cost_estimating, policy_checking, confirmed, applying, and others
# Page 2 with 20 items per page
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs?page[number]=2&page[size]=20"
# Check pagination info
curl -sf --header "Authorization: Bearer $TOKEN" \
"$BASE_URL/workspaces/$WORKSPACE_ID/runs" | \
jq '.meta.pagination'
The /runs endpoint has a special rate limit of 30 requests/minute (not 30/second like most endpoints). Plan accordingly when scripting.
tfc-run-logs: Get plan/apply logs for a runtfc-run-status: Quick status check for a runtfc-workspace-runs: Convenience wrapper for known workspacestools
Scaffold a new ComfyUI custom-node repo (pyproject, CI, release-please, vitest+pytest, JS extension skeleton) in the picker/gesture vein. Use when bootstrapping or init-ing a comfyui node pack.
tools
Orchestrate a ComfyUI node pack from idea to registry: scaffold, create + seed the repo, open the gitops adoption PR. Use when releasing or spinning up a new comfyui node pack.
testing
macOS EndpointSecurity/EDR high CPU & battery drain. Use when Kandji ESF / XProtect pegs a core; trace the exec storm via powermetrics + eslogger.
development
odiff pixel-by-pixel image diffing. Use when comparing screenshots, detecting visual regressions, diffing before/after PNGs, asserting golden images.