spend-watch
Autonomous cloud-cost analyst across Neon, Vercel, Railway and GitHub Actions - pulls per-object usage, attributes it to the biggest drivers, root-causes…
Skill by aeonfun
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/aeonfun-spend-watch
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend, devops, cloud
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/spend-watch
What's inside
- Skill name
spend-watch- Description
- Autonomous cloud-cost analyst across Neon, Vercel, Railway and GitHub Actions - pulls per-object usage, attributes it to the biggest drivers, root-causes each, and emits recommendations ranked by real signal (idle %, over-allowance, failure rate) with dollar figures only where the billing API returns real ones (and, armed, applies safe cost levers).
- License
- MIT
- Metadata
- var: · mode: write · title: Spend Watch · category: dev
- Instructions
- 325 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
- Instructions read files in your home folder (~/.ssh, ~/.aws…)
Files (1)
- SKILL.md
SKILL.md (first lines)
Today is ${today}.
> **${var}** — scope selector + optional arm flag.
> - **empty** / `all` → sweep every platform whose secret is present, emit one combined digest.
> - `neon` | `vercel` | `railway` | `actions` → run one adapter only.
> - prepend `arm:` (e.g. `arm:neon`, `arm:actions`) → authorize the adapter's **safe write levers** for this run. Without `arm:` the skill is read-only: it recommends, never mutates.
> - `dry-run` appended anywhere → build the digest but do not `./notify` (for testing).
>
> Runs unattended — treat `${var}` as final, no confirmation step, except a delete/mutation always re-reads the target's current state before acting (see each adapter's arm rules).
This skill is a cost **analyst**, not a bill alarm. Each run answers, per platform:
1. **Attribution** — what is consuming the most? Rank drivers by dollars (or the resource unit that maps to dollars), down to the specific object: service, branch, route, RPC method, workflow. Top-N with each line's % share.
2. **Root cause** — *why* is that line expensive?
3. **Recommendation** — a ranked action list, each carrying: the concrete lever, an effort/risk tag, whether it's armable now, and a **saving in real dollars ONLY when the platform's billing API returns real dollars** (Railway `currentUsage`, Actions overage). Everywhere else there is **no dollar figure** — the line carries its real signal instead (idle-awake %, % over the included allowance, cache-miss rate, stale-preview count, failure rate). Never invent a `$X/mo`.
**Dollars-only-when-real is the core rule.** A fabricated "$5/mo" is worse than the true signal "idle-awake 71%". Rank each recommendation by: real-$ saving first (when known), then signal magnitude × how actionable it is (armable > 1-click > code-change > investigate). The recommendation is the deliverable; the signal justifies it; the dollar is a bonus only when the API hands it over.
Across platforms (`all`): a roll-up — the **real** spend where billing exposes it (Railway $, Actions $), the biggest signal-ranked driver anywhere, and the top actions fleet-wide. No synthetic grand total.
The monitoring (deltas, real budgets, signal thresholds) is the *trend context and the trigger*; the deliverable is the ranked recommendations.
---
## Shared setup (every run)
1. Read `memory/MEMORY.md` for context and `memory/spend-config.md` for real-$ budgets, signal thresholds, and ignore-lists (see the config schema at the bottom). If `spend-config.md` is missing, run with the built-in defaults and note `NO_CONFIG` in the log — recommendations still work; they rank by signal regardless.
2. Read the last 7 days of `memory/logs/` — used to detect *newly* expensive drivers vs ongoing, and to avoid repeat-nagging a recommendation already sent.
3. Parse `${var}`:
```bash
RAW="$(printf '%s' "${var}" | tr '[:upper:]' '[:lower:]' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
ARM=0; case "$RAW" in arm:*) ARM=1; RAW="${RAW#arm:}";; esac
DRYRUN=0; case "$RAW" in *dry-run*) DRYRUN=1; RAW="$(printf '%s' "$RAW" | sed 's/dry-run//g' | tr -s ' ')";; esac
RAW="$(printf '%s' "$RAW" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
case "$RAW" in
""|all) SCOPE=all ;;
neon|vercel|railway|actions) SCOPE="$RAW" ;;
*) SCOPE=all ;; # unrecognized -> full sweep, note it in the log
esac
```
4. Run the matching adapter(s). Each adapter **self-skips** if its secret is absent — log `<platform>: SKIP no-secret` and continue. In `all` mode, run every adapter whose secret is present, then run the **Synthesis** section.
### Common adapter contract
Every adapter produces the same intermediate shape (the model builds it in memory, one entry per cost driver):
```
{ platform, object, metric, amount, share_pct, signal, real_usd, saving_usd,
trend, root_cause, recommendation, effort, armable }
```
- `effort` ∈ `armable` | `1-click` | `code-change` | `investigate`.
- `real_usd` / `saving_usd` — populated **only** from a billing API that returns actual dollars (Railway `customer.currentUsage`, Actions summed `netAmount`/overage). Otherwise **`null`** — do not compute a dollar figure from a config rate. There is no cost-rate multiplication anywhere in this skill.
- `signal` — the real, dollar-free magnitude that justifies the line and drives its rank when `saving_usd` is null: e.g. `idle-awake 71%`, `18% over included minutes`, `stale-previews 300`, `failure-rate 51%`, `RSS 4.6× working set`. Always present.
- `metric`/`amount` — the raw usage unit (compute-hours, minutes, GB-hrs, requests) behind the signal.
- `trend` ∈ `new` | `up` | `flat` | `down`, computed against the prior snapshot.
### State ledger
Each adapter reads and rewrites `memory/state/spend-<platform>.json`:
```json
{
"updated_at": "<ISO8601>",
"drivers": [ { "object": "...", "metric": "...", "amount": 0, "signal": "idle-awake 71%", "real_usd": null } ],
"recommendations_sent": [ { "id": "neon:tighten-timeout:ep-x", "sent": "<ISO8601>", "signal": "idle-awake 71%" } ]
}
```
`recommendations_sent` is how the skill avoids repeat-nagging: if a rec's `id` was sent within the config's `nag_cooldown_days` (default 14) and the driver hasn't grown, downgrade it to a one-line "(still open)" mention rather than re-ranking it at the top.
### Notify
The `./notify` body is the **ranked recommendation list**, not a raw usage dump. Severity gate:
- `critical` — a **real-$** breach: Railway `currentUsage` over `budgets_usd_month.railway` or its `usageLimit`, or Actions over the global included allowance (real overage $). Real dollars only — a signal alone never escalates to critical.
- `warn` — an actionable recommendation exists, or a driver trending `up`/`new` past the config's `alert_share_pct` (signal-based, no dollars needed).
- `info` — nothing worth acting on. **Send nothing** (silence is the signal, like `price-alert`). Just log.
`dry-run` suppresses the send entirely.
---
## Adapter: actions (GitHub Actions — build-first, highest feasibility)
Aeon runs *on* GitHub Actions, so this adapter optimizes the agent's own runner bill. Auth is `gh` (uses `GH_GLOBAL` ambiently as `GH_TOKEN`) — **not** `secretcurl` (`GH_GLOBAL` ends in `_GLOBAL`, which secretcurl does not substitute).
### 1. Pull usage — account-global first, per-repo only for attribution
**Billing is ONE account-wide pool.** Included minutes are a single global allowance and overage is billed on the account total — NOT per repo. So the budget check is global; per-repo is only for attributing *where* the global minutes go. Never gate savings on a per-repo dollar figure.
```bash
ME="$(gh api user --jq .login)"
# Global account usage — the budget number. Probe both; branch on HTTP status.
gh api "/users/$ME/settings/billing/usage" 2>/dev/null # enhanced: per-repo-per-day rows {quantity(min),grossAmount,discountAmount,netAmount,repositoryName}. SUM across ALL rows = global minutes + global net $ this cycle.
gh api "/users/$ME/settings/billing/actions" 2>/dev/null # classic (410 on migrated accounts): total_minutes_used + included_minutes (the GLOBAL allowance) + minutes_used_breakdown{UBUNTU,MACOS,WINDOWS}
gh api "/users/$ME/settings/billing/shared-storage" 2>/dev/null # global artifacts+packages storage GB
```
Note on the enhanced endpoint: it returns per-repo rows, but that's a reporting breakdown of one global pool — **sum them for the account figure**, group by `repositoryName` only to attribute. `netAmount` is real billed $ after the included-minutes discount; sum of `netAmount` = your true global Actions bill. Public repos are free/unlimited and don't draw the pool; only private-repo minutes consume the global allowance.
```bash
# Attribution: which repos/workflows drive the global minutes. Scope = every repo with usage
# in the billing rows this cycle (NOT a fixed private-list). Optional actions.repos in config
# just narrows/orders which repos to fetch per-workflow detail for.
for repo in <repos appearing in the billing rows>; do
gh api "/repos/$repo/actions/cache/usage" 2>/dev/null
gh api "/repos/$repo/actions/artifacts?per_page=100" --jq '[.artifacts[]|{name,size:.size_in_bytes,created:.created_at,expires:.expires_at,id}]' 2>/dev/null
gh api "/repos/$repo/actions/runs?per_page=100" --jq '[.workflow_runs[]|{name,workflow_id,run_started_at,updated_at,conclusion}]' 2>/dev/null
done
```
### 2. Budget check (global) + attribute (per-repo/workflow)
**Budget check — global only.** Compare account `total_minutes_used` vs `included_minutes` (classic) or summed `netAmount` vs `budgets_usd_month.actions` (enhanced). Inside the included allowance → net $0 → nothing to save (say so; it's `info`). Over the allowance → the overage $ is the *only* real Actions saving, and it's global. This is the single number that decides severity.
**Attribution — per-repo → per-workflow.** Only once there's a global overage (or to pre-empt one) rank which repos/workflows drive the pool by **minutes** (the signal), so a trim targets the biggest draw. Dollars come only from real `netAmount`/overage; if billing $ is absent, rank by minutes and % of the included allowance — never multiply by a rate.From aeonfun/aeon, MIT.
More from aeonfun/aeon
- 0.722score
anatomy
aeonfun
Build crafted, highly detailed, interactive isometric SVG figures that explain a technical idea as a real physical object (a test rig, a dial gauge, a cabinet…
SkillAFreshness: A★ 782Claude Code +9 - 0.719score
base-mcp
aeonfun
Access a Base Account via the Base MCP server (mcp.base.org) - wallet, portfolio, sending, swapping, signing, x402 payments, batched calls, and transaction…
SkillAFreshness: A★ 782Claude Code +9 - 0.718score
aeon
aeonfun
Set up and run an Aeon agent instance - get started from scratch, pick which skills to turn on or install more from packs, reschedule or change what runs…
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
hunter-22
aeonfun
Scan the ClawHunter agent bounty marketplace for opportunities that genuinely match this agent's real capabilities (code, security research, writing) and…
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
get-started
aeonfun
First-run setup for the Aeon plugin.
SkillAFreshness: A★ 782Claude Code +9 - 0.715score
seo-audit
aeonfun
Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
fetch-tweets
aeonfun
Search and curate X/Twitter behind one selector - keyword, topic roundup, a single or tracked-account digest, an X list, or the AI-agent buzz preset -…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
github-trending
aeonfun
Curated trending across GitHub repos and the Hugging Face Hub (models, datasets, spaces) - filtered, clustered, and labeled by momentum with a one-line…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
bd-radar
aeonfun
Business-development radar across your product family - find who's building, forking, integrating, and mentioning your products, ranked into a…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
digest
aeonfun
Generate and send a digest on a configurable topic, optionally pulling RSS/Atom feeds as an input source alongside web + X signal
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
feedback-builder
aeonfun
Point Aeon at a service's /feedback endpoint - pull what agents reported (bugs, missing features), triage and cluster it, then build the best accepted request…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
heartbeat
aeonfun
Ambient fleet-health check that surfaces anything worth attention (default), or an on-demand priority brief - the 3 things to focus on, why now, and what…
SkillAFreshness: A★ 782Claude Code +9
Compare and alternatives
Featured in
Signals
- Stars
- 782
- Forks
- 292
- Open issues
- 0
- Last commit (this folder)
- Aug 7, 2026 (2 months ago)
- Last release
- Jul 9, 2026 (3 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/aeonfun/aeon
- Website
- www.aeon.fun/
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from aeonfun
- 0.722score
anatomy
aeonfun
Build crafted, highly detailed, interactive isometric SVG figures that explain a technical idea as a real physical object (a test rig, a dial gauge, a cabinet…
SkillAFreshness: A★ 782Claude Code +9 - 0.719score
base-mcp
aeonfun
Access a Base Account via the Base MCP server (mcp.base.org) - wallet, portfolio, sending, swapping, signing, x402 payments, batched calls, and transaction…
SkillAFreshness: A★ 782Claude Code +9 - 0.718score
aeon
aeonfun
Set up and run an Aeon agent instance - get started from scratch, pick which skills to turn on or install more from packs, reschedule or change what runs…
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
get-started
aeonfun
First-run setup for the Aeon plugin.
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
hunter-22
aeonfun
Scan the ClawHunter agent bounty marketplace for opportunities that genuinely match this agent's real capabilities (code, security research, writing) and…
SkillAFreshness: A★ 782Claude Code +9 - 0.715score
seo-audit
aeonfun
Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles…
SkillAFreshness: A★ 782Claude Code +9
Cite this page
spend-watch skill. Agent Mart. https://agentmart.dev/skills/aeonfun-spend-watch (last updated 2026-10-24)