OPS ► REVENUE & COSTS skill
OPS on-demand: This skill should be used when the user asks to "burn rate", "runway", or…
by Lifecycle-Innovations-Limited·MIT license·★ 543 Stars on the repo·GitHub ↗
npx degit Lifecycle-Innovations-Limited/claude-ops/claude-ops/skills/ops-revenue#main ~/.claude/skills/ops-revenueChecked ·commit main
Inside this skill
SKILL.md · the author's own words# OPS ► REVENUE & COSTS Load `ops-rules` before acting. Public repo (no personal data). Outbound: one draft → one approval → one send. If `AskUserQuestion` / `Work… ## Runtime Context Before executing, load available context: 1. **Preferences**: Read `${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.json` - `timezone` — display all timestamps correctly 2. **Daemon health**: Read `${CLAUDE_PLUGIN_DATA_DIR}/daemon-health.json` - If `action_needed` is not null → surface it before the cost report 3. **Secrets**: AWS Cost Explorer requires credentials. ### Secret Resolution
Word-for-word excerpt, not a result. Read the full SKILL.md ↓
Files of OPS ► REVENUE & COSTS
Show the full text270 lines
OPS ► REVENUE & COSTS
Load ops-rules before acting. Public repo (no personal data). Outbound: one draft → one approval → one send. If AskUserQuestion / Workflow are missing, follow Rule 10 in ops-rules (Hermes: numbered options / two-turn Telegram card; delegate_task).
Runtime Context
Before executing, load available context:
Preferences: Read
${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.jsontimezone— display all timestamps correctly
Daemon health: Read
${CLAUDE_PLUGIN_DATA_DIR}/daemon-health.json- If
action_neededis not null → surface it before the cost report
- If
Secrets: AWS Cost Explorer requires credentials.
Secret Resolution
- AWS: check
$AWS_PROFILE/$AWS_ACCESS_KEY_ID→doppler secrets get AWS_ACCESS_KEY_ID --plain→ vault query cmd from prefs - If no credentials available, report "AWS costs unavailable — credentials not configured" and show only the revenue pipeline from registry
- AWS: check
CLI/API Reference
AWS burn doctrine (CRITICAL — 2026-07-22)
Never report plain UnblendedCost / NetUnblendedCost totals as "spend".
Startup credits, SPP discounts, and Savings Plan negation make those nets ≈ $0
while real Usage burn is hundreds/day. Always use RECORD_TYPE=Usage for
burn, pace, spikes, runway, and Bedrock. Show credits only as a mask line.
Canonical helper (prefer this over raw aws ce):
${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh snapshot 2>/dev/null || echo '{}'
${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh all 2>/dev/null || true
| Command | Usage | Output |
|---|---|---|
scripts/aws-usage-cost.sh snapshot |
MTD/prev Usage burn + 7d daily + top services + credit mask | JSON |
scripts/aws-usage-cost.sh daily 7 |
Last N days Usage totals | JSON array |
scripts/aws-usage-cost.sh by-service mtd |
MTD Usage by service | JSON array |
scripts/aws-usage-cost.sh record-types |
Credit / Usage / SP breakdown (mask only) | JSON array |
aws ce get-cost-and-usage … --filter '{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}}' |
Raw Usage-only CE (fallback if helper missing) | Cost JSON |
aws ce list-savings-plans-purchase-recommendation |
Savings plan recommendations | JSON |
Phase 1 — Gather financial data in parallel
FinOps dashboard — canonical revenue + burn
If FINOPS_DASHBOARD_URL and FINOPS_OPS_API_TOKEN are configured, the
dashboard is the single source of truth for per-project MRR, 30d revenue,
and current burn. Per-DBA breakdown comes from the Stripe revenue
snapshots ingested via /api/ops/revenue. Falls open to {} if unset —
the per-source AWS / RevenueCat queries below run as fallback.
If the dashboard current_month_spend is ≈ $0 while Usage burn from
aws-usage-cost.sh is material, trust the helper (dashboard may still be
credit-masked or ingest-empty). Always dual-check with the Usage helper.
${CLAUDE_PLUGIN_ROOT}/scripts/finops-bridge.sh snapshot 2>/dev/null || echo "{}"
${CLAUDE_PLUGIN_ROOT}/scripts/finops-bridge.sh revenue project 2>/dev/null || echo "{}"
When the dashboard returns data, render the per-project MRR section from
groups[] rather than from RevenueCat-only data.
AWS costs — Usage burn (authoritative)
${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh snapshot 2>/dev/null || echo '{}'
Fallback if helper missing:
USAGE_FILTER='{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}}'
aws ce get-cost-and-usage \
--time-period "Start=$(date +%Y-%m-01),End=$(date +%Y-%m-%d)" \
--granularity MONTHLY \
--metrics "UnblendedCost" \
--filter "$USAGE_FILTER" \
--group-by "Type=DIMENSION,Key=SERVICE" \
--output json 2>/dev/null
AWS costs (last 3 months Usage trend)
USAGE_FILTER='{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}}'
aws ce get-cost-and-usage \
--time-period "Start=$(date -v-3m +%Y-%m-01 2>/dev/null || date -d '3 months ago' +%Y-%m-01),End=$(date +%Y-%m-%d)" \
--granularity MONTHLY \
--metrics "UnblendedCost" \
--filter "$USAGE_FILTER" \
--output json 2>/dev/null
AWS credits / discount mask (not spend)
${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh record-types 2>/dev/null || echo '[]'
aws ce list-savings-plans-purchase-recommendation --output json 2>/dev/null || echo '{}'
aws ce get-credits --output json 2>/dev/null || echo "credits API unavailable"
AWS cost forecast (end of month)
Note: CE forecasts are often net-of-credits. Prefer eom_pace from
aws-usage-cost.sh snapshot (7d Usage avg × days in month) as the burn forecast.
aws ce get-cost-forecast \
--time-period "Start=$(date +%Y-%m-%d),End=$(date +%Y-%m-28)" \
--metric "UNBLENDED_COST" \
--granularity MONTHLY \
--output json 2>/dev/null
Project registry (revenue stage)
cat "${CLAUDE_PLUGIN_ROOT}/scripts/registry.json" 2>/dev/null | jq '[.projects[] | {alias, name, stage: (.revenue_stage // .revenue.stage // "pre-revenue"), mrr: (.mrr // 0), source: (.source // "git"), type: (.type // "repo")}]'
External project revenue (Shopify, custom SaaS)
${CLAUDE_PLUGIN_ROOT}/bin/ops-external 2>/dev/null || echo '[]'
For Shopify projects showing status: "healthy", pull GMV via Shopify Admin API:
# For each Shopify project in registry with valid credentials:
STORE_URL="[from project.shopify.store_url]"
TOKEN="[from env var named in project.shopify.credential_key]"
curl -s -H "X-Shopify-Access-Token: $TOKEN" \
"https://$STORE_URL/admin/api/2024-10/orders.json?status=any&created_at_min=$(date -v-30d +%Y-%m-%dT00:00:00Z 2>/dev/null)&limit=250" 2>/dev/null
Include Shopify GMV in the revenue pipeline table with source=shopify.
Phase 2 — Render dashboard
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OPS ► REVENUE & COSTS — [month]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AWS USAGE BURN (RECORD_TYPE=Usage — not credit-masked net)
This month usage: $[X] ← from aws-usage-cost.sh mtd_usage
Forecast (EOM pace): $[X] ← eom_pace (7d Usage avg × days)
Last month usage: $[X]
MoM change: [+/-X%]
7d avg/day: $[X]
Top services (Usage):
[service] $[X] ([%] of usage)
[service] $[X]
...
CREDITS / MASK (do not report as low spend)
Credits applied MTD: $[X] (record_types Credit)
Discounts MTD: $[X]
Net after mask: ~$0 is EXPECTED when credits cover burn
Credits remaining: $[X] (if API available)
Expires: [date]
Months cover at pace: [N]
REVENUE PIPELINE
PROJECT SOURCE STAGE MRR/GMV STATUS
──────────────────────────────────────────────────────────────
[project] git [stage] $[X] [status]
[project] shopify [stage] $[X] GMV [status]
[project] custom [stage] $[X] [status]
...
──────────────────────────────────────────────────────────────
TOTAL MRR $[X]
TOTAL SHOPIFY GMV (30d) $[X]
RUNWAY ESTIMATE
Monthly burn (AWS): $[X]
Total MRR: $[X]
Net burn: $[X/month]
Credits cover: [N months]
Cash runway: [depends on external data]
──────────────────────────────────────────────────────
Use batched AskUserQuestion calls (max 4 options each):
AskUserQuestion call 1:
[Drill into AWS costs by service]
[Show cost anomalies (spike detection)]
[Export cost report]
[More...]
AskUserQuestion call 2 (only if "More..."):
[Update project revenue stage]
[Set budget alert]
Route by $ARGUMENTS
| Argument | Action |
|---|---|
| costs | Show only AWS cost breakdown |
| credits | Show only credits and expiry |
| revenue | Show only revenue pipeline |
| runway | Calculate and show runway |
| (empty) | Show full dashboard |
Use AskUserQuestion after the dashboard for next action.
Native tool usage
WebFetch — billing API fallback
When aws ce commands fail or return incomplete data, use WebFetch to query the AWS Cost Explorer API directly. Also useful for fetching Stripe/billing provider data if configured.
Write — export reports
When user selects "Export cost report" (option c), use Write to save the report as a dated file:
Write(file_path: "/tmp/ops-revenue-[date].md", content: "[formatted report]")
| 1 | |
| 2 | name ops-revenue |
| 3 | description "OPS on-demand: This skill should be used when the user asks to \"burn rate\", \"runway\", or…" |
| 4 | argument-hint '[costs|revenue|credits|runway|all]' |
| 5 | allowed-tools |
| 6 | - Bash |
| 7 | - Read |
| 8 | - Grep |
| 9 | - Glob |
| 10 | - Skill |
| 11 | - AskUserQuestion |
| 12 | - WebFetch |
| 13 | - Write |
| 14 | effort low |
| 15 | maxTurns 20 |
| 16 | disallowedTools |
| 17 | - Edit |
| 18 | - NotebookEdit |
| 19 | |
| 20 | |
| 21 | # OPS ► REVENUE & COSTS |
| 22 | |
| 23 | Load `ops-rules` before acting. Public repo (no personal data). Outbound: one draft → one approval → one send. If `AskUserQuestion` / `Workflow` are missing, follow Rule 10 in `ops-rules` (Hermes: numbered options / two-turn Telegram card; `delegate_task`). |
| 24 | |
| 25 | ## Runtime Context |
| 26 | |
| 27 | Before executing, load available context: |
| 28 | |
| 29 | **Preferences**: Read `${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.json` |
| 30 | `timezone` — display all timestamps correctly |
| 31 | |
| 32 | **Daemon health**: Read `${CLAUDE_PLUGIN_DATA_DIR}/daemon-health.json` |
| 33 | If `action_needed` is not null → surface it before the cost report |
| 34 | |
| 35 | **Secrets**: AWS Cost Explorer requires credentials. |
| 36 | ### Secret Resolution |
| 37 | AWS: check `$AWS_PROFILE` / `$AWS_ACCESS_KEY_ID` → `doppler secrets get AWS_ACCESS_KEY_ID --plain` → vault query cmd from prefs |
| 38 | If no credentials available, report "AWS costs unavailable — credentials not configured" and show only the revenue pipeline from registry |
| 39 | |
| 40 | ## CLI/API Reference |
| 41 | |
| 42 | ### AWS burn doctrine (CRITICAL — 2026-07-22) |
| 43 | |
| 44 | **Never report plain `UnblendedCost` / `NetUnblendedCost` totals as "spend".** |
| 45 | Startup credits, SPP discounts, and Savings Plan negation make those nets ≈ $0 |
| 46 | while real Usage burn is hundreds/day. **Always** use `RECORD_TYPE=Usage` for |
| 47 | burn, pace, spikes, runway, and Bedrock. Show credits only as a mask line. |
| 48 | |
| 49 | Canonical helper (prefer this over raw `aws ce`): |
| 50 | |
| 51 | |
| 52 | ${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh snapshot 2>/dev/null || echo '{}' |
| 53 | |
| 54 | |
| 55 | |
| 56 | ${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh all 2>/dev/null || true |
| 57 | |
| 58 | |
| 59 | | Command | Usage | Output | |
| 60 | | ------- | ----- | ------ | |
| 61 | | `scripts/aws-usage-cost.sh snapshot` | MTD/prev Usage burn + 7d daily + top services + credit mask | JSON | |
| 62 | | `scripts/aws-usage-cost.sh daily 7` | Last N days Usage totals | JSON array | |
| 63 | | `scripts/aws-usage-cost.sh by-service mtd` | MTD Usage by service | JSON array | |
| 64 | | `scripts/aws-usage-cost.sh record-types` | Credit / Usage / SP breakdown (mask only) | JSON array | |
| 65 | | `aws ce get-cost-and-usage … --filter '{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}}'` | Raw Usage-only CE (fallback if helper missing) | Cost JSON | |
| 66 | | `aws ce list-savings-plans-purchase-recommendation` | Savings plan recommendations | JSON | |
| 67 | |
| 68 | |
| 69 | |
| 70 | ## Phase 1 — Gather financial data in parallel |
| 71 | |
| 72 | ### FinOps dashboard — canonical revenue + burn |
| 73 | |
| 74 | If `FINOPS_DASHBOARD_URL` and `FINOPS_OPS_API_TOKEN` are configured, the |
| 75 | dashboard is the single source of truth for per-project MRR, 30d revenue, |
| 76 | and current burn. Per-DBA breakdown comes from the Stripe revenue |
| 77 | snapshots ingested via `/api/ops/revenue`. Falls open to `{}` if unset — |
| 78 | the per-source AWS / RevenueCat queries below run as fallback. |
| 79 | |
| 80 | **If the dashboard `current_month_spend` is ≈ $0 while Usage burn from |
| 81 | `aws-usage-cost.sh` is material, trust the helper** (dashboard may still be |
| 82 | credit-masked or ingest-empty). Always dual-check with the Usage helper. |
| 83 | |
| 84 | |
| 85 | ${CLAUDE_PLUGIN_ROOT}/scripts/finops-bridge.sh snapshot 2>/dev/null || echo "{}" |
| 86 | |
| 87 | |
| 88 | |
| 89 | ${CLAUDE_PLUGIN_ROOT}/scripts/finops-bridge.sh revenue project 2>/dev/null || echo "{}" |
| 90 | |
| 91 | |
| 92 | When the dashboard returns data, render the per-project MRR section from |
| 93 | `groups[]` rather than from RevenueCat-only data. |
| 94 | |
| 95 | ### AWS costs — Usage burn (authoritative) |
| 96 | |
| 97 | |
| 98 | ${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh snapshot 2>/dev/null || echo '{}' |
| 99 | |
| 100 | |
| 101 | Fallback if helper missing: |
| 102 | |
| 103 | |
| 104 | USAGE_FILTER='{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}}' |
| 105 | aws ce get-cost-and-usage \ |
| 106 | --time-period "Start=$(date +%Y-%m-01),End=$(date +%Y-%m-%d)" \ |
| 107 | --granularity MONTHLY \ |
| 108 | --metrics "UnblendedCost" \ |
| 109 | --filter "$USAGE_FILTER" \ |
| 110 | --group-by "Type=DIMENSION,Key=SERVICE" \ |
| 111 | --output json 2>/dev/null |
| 112 | |
| 113 | |
| 114 | ### AWS costs (last 3 months Usage trend) |
| 115 | |
| 116 | |
| 117 | USAGE_FILTER='{"Dimensions":{"Key":"RECORD_TYPE","Values":["Usage"]}}' |
| 118 | aws ce get-cost-and-usage \ |
| 119 | --time-period "Start=$(date -v-3m +%Y-%m-01 2>/dev/null || date -d '3 months ago' +%Y-%m-01),End=$(date +%Y-%m-%d)" \ |
| 120 | --granularity MONTHLY \ |
| 121 | --metrics "UnblendedCost" \ |
| 122 | --filter "$USAGE_FILTER" \ |
| 123 | --output json 2>/dev/null |
| 124 | |
| 125 | |
| 126 | ### AWS credits / discount mask (not spend) |
| 127 | |
| 128 | |
| 129 | ${CLAUDE_PLUGIN_ROOT}/scripts/aws-usage-cost.sh record-types 2>/dev/null || echo '[]' |
| 130 | |
| 131 | |
| 132 | |
| 133 | aws ce list-savings-plans-purchase-recommendation --output json 2>/dev/null || echo '{}' |
| 134 | aws ce get-credits --output json 2>/dev/null || echo "credits API unavailable" |
| 135 | |
| 136 | |
| 137 | ### AWS cost forecast (end of month) |
| 138 | |
| 139 | Note: CE forecasts are often net-of-credits. Prefer `eom_pace` from |
| 140 | `aws-usage-cost.sh snapshot` (7d Usage avg × days in month) as the burn forecast. |
| 141 | |
| 142 | |
| 143 | aws ce get-cost-forecast \ |
| 144 | --time-period "Start=$(date +%Y-%m-%d),End=$(date +%Y-%m-28)" \ |
| 145 | --metric "UNBLENDED_COST" \ |
| 146 | --granularity MONTHLY \ |
| 147 | --output json 2>/dev/null |
| 148 | |
| 149 | ### Project registry (revenue stage) |
| 150 | |
| 151 | |
| 152 | cat "${CLAUDE_PLUGIN_ROOT}/scripts/registry.json" 2>/dev/null | jq '[.projects[] | {alias, name, stage: (.revenue_stage // .revenue.stage // "pre-revenue"), mrr: (.mrr // 0), source: (.source // "git"), type: (.type // "repo")}]' |
| 153 | |
| 154 | |
| 155 | ### External project revenue (Shopify, custom SaaS) |
| 156 | |
| 157 | |
| 158 | ${CLAUDE_PLUGIN_ROOT}/bin/ops-external 2>/dev/null || echo '[]' |
| 159 | |
| 160 | |
| 161 | For Shopify projects showing `status: "healthy"`, pull GMV via Shopify Admin API: |
| 162 | |
| 163 | |
| 164 | # For each Shopify project in registry with valid credentials: |
| 165 | STORE_URL="[from project.shopify.store_url]" |
| 166 | TOKEN="[from env var named in project.shopify.credential_key]" |
| 167 | curl -s -H "X-Shopify-Access-Token: $TOKEN" \ |
| 168 | "https://$STORE_URL/admin/api/2024-10/orders.json?status=any&created_at_min=$(date -v-30d +%Y-%m-%dT00:00:00Z 2>/dev/null)&limit=250" 2>/dev/null |
| 169 | |
| 170 | |
| 171 | Include Shopify GMV in the revenue pipeline table with source=shopify. |
| 172 | |
| 173 | |
| 174 | |
| 175 | ## Phase 2 — Render dashboard |
| 176 | |
| 177 | |
| 178 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 179 | OPS ► REVENUE & COSTS — [month] |
| 180 | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 181 | |
| 182 | AWS USAGE BURN (RECORD_TYPE=Usage — not credit-masked net) |
| 183 | This month usage: $[X] ← from aws-usage-cost.sh mtd_usage |
| 184 | Forecast (EOM pace): $[X] ← eom_pace (7d Usage avg × days) |
| 185 | Last month usage: $[X] |
| 186 | MoM change: [+/-X%] |
| 187 | 7d avg/day: $[X] |
| 188 | |
| 189 | Top services (Usage): |
| 190 | [service] $[X] ([%] of usage) |
| 191 | [service] $[X] |
| 192 | ... |
| 193 | |
| 194 | CREDITS / MASK (do not report as low spend) |
| 195 | Credits applied MTD: $[X] (record_types Credit) |
| 196 | Discounts MTD: $[X] |
| 197 | Net after mask: ~$0 is EXPECTED when credits cover burn |
| 198 | Credits remaining: $[X] (if API available) |
| 199 | Expires: [date] |
| 200 | Months cover at pace: [N] |
| 201 | |
| 202 | REVENUE PIPELINE |
| 203 | PROJECT SOURCE STAGE MRR/GMV STATUS |
| 204 | ────────────────────────────────────────────────────────────── |
| 205 | [project] git [stage] $[X] [status] |
| 206 | [project] shopify [stage] $[X] GMV [status] |
| 207 | [project] custom [stage] $[X] [status] |
| 208 | ... |
| 209 | ────────────────────────────────────────────────────────────── |
| 210 | TOTAL MRR $[X] |
| 211 | TOTAL SHOPIFY GMV (30d) $[X] |
| 212 | |
| 213 | RUNWAY ESTIMATE |
| 214 | Monthly burn (AWS): $[X] |
| 215 | Total MRR: $[X] |
| 216 | Net burn: $[X/month] |
| 217 | Credits cover: [N months] |
| 218 | Cash runway: [depends on external data] |
| 219 | |
| 220 | ────────────────────────────────────────────────────── |
| 221 | |
| 222 | |
| 223 | Use **batched AskUserQuestion calls** (max 4 options each): |
| 224 | |
| 225 | AskUserQuestion call 1: |
| 226 | |
| 227 | |
| 228 | [Drill into AWS costs by service] |
| 229 | [Show cost anomalies (spike detection)] |
| 230 | [Export cost report] |
| 231 | [More...] |
| 232 | |
| 233 | |
| 234 | AskUserQuestion call 2 (only if "More..."): |
| 235 | |
| 236 | |
| 237 | [Update project revenue stage] |
| 238 | [Set budget alert] |
| 239 | |
| 240 | |
| 241 | |
| 242 | |
| 243 | ## Route by `$ARGUMENTS` |
| 244 | |
| 245 | | Argument | Action | |
| 246 | | -------- | ---------------------------- | |
| 247 | | costs | Show only AWS cost breakdown | |
| 248 | | credits | Show only credits and expiry | |
| 249 | | revenue | Show only revenue pipeline | |
| 250 | | runway | Calculate and show runway | |
| 251 | | (empty) | Show full dashboard | |
| 252 | |
| 253 | Use AskUserQuestion after the dashboard for next action. |
| 254 | |
| 255 | |
| 256 | |
| 257 | ## Native tool usage |
| 258 | |
| 259 | ### WebFetch — billing API fallback |
| 260 | |
| 261 | When `aws ce` commands fail or return incomplete data, use `WebFetch` to query the AWS Cost Explorer API directly. Also useful for fetching Stripe/billing provider data if configured. |
| 262 | |
| 263 | ### Write — export reports |
| 264 | |
| 265 | When user selects "Export cost report" (option c), use `Write` to save the report as a dated file: |
| 266 | |
| 267 | |
| 268 | Write(file_path: "/tmp/ops-revenue-[date].md", content: "[formatted report]") |
| 269 | |
| 270 |
Discussion
Browse more free Claude skills.