agentsclimarketplace

Render finance dashboard

Skill ya5huk/findash/skills/render-finance-dashboard

Use when the user says "render dashboard", "show my finances", "build the dashboard", or any morning-summary equivalent. Reads SQLite, fetches live prices/FX from Yahoo Finance, fills the HTML template, and writes a self-contained dashboard to `output/dashboard.html`.From its SKILL.md

Install
npx -y skills add ya5huk/findash --skill render-finance-dashboard

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 19 stars19 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.4 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it

render-finance-dashboard

You render the booky finance dashboard from the current state of data/finance.db. The visual design is fixed by the template; you only fill it with data. The mechanical part (SQL → HTML, live-price fetch, asset inlining) lives in scripts/render_dashboard.py — invoke it, don't re-derive it.

Where things live

  • Canonical renderer: scripts/render_dashboard.py
  • HTML template (placeholders in {{NAME}} form): templates/dashboard.html.tpl
  • CSS: templates/styles.css — inlined into the HTML at render time
  • Chart constructors: templates/charts.js — inlined into the HTML
  • Vendored offline assets (gitignored, produced by scripts/bundle-assets.py):
    • templates/vendor/chart.umd.min.js
    • templates/vendor/chartjs-adapter-date-fns.bundle.min.js
    • templates/vendor/fonts-inline.css (EB Garamond + Cormorant Garamond, base64 woff2)
  • Telegram credentials: the [telegram] section of .secrets/findash (bot_token=… and chat_id=…)
  • Local DB: data/finance.db
  • Output: a single self-contained file at output/dashboard.html
  • SQL schema and example queries: docs/sqlite-schema.md
  • Visual rules: docs/design-system.md

Flow

  1. Run the renderer. From the project root:

    python3 scripts/render_dashboard.py
    

    The script handles everything mechanical:

    • Live-fetches prices for currently-held securities and USD/ILS, GBP/ILS FX rates from Yahoo Finance (query1.finance.yahoo.com/v8/finance/chart/{symbol}). User-Agent header required.
    • Yahoo symbol translation: RR.LSERR.L. Quote units: USD direct; LSE pence (÷100 → GBP); TASE agorot (÷100 → ILS).
    • Persists fetched prices into prices and the new FX into fx_rates so a history accumulates day-by-day.
    • Computes net worth in ILS, brokerage market value, unrealized P/L per position.
    • Excludes accounts with closed_on IS NOT NULL from Cash and from the headline (they still show in SQLite-data).
    • Sorts the positions table by ILS-equivalent market value, descending (so SPY ranks above RR.LSE despite fewer shares).
    • Orders brokerage deposits newest first.
    • Builds the SQLite-data debug tabs (first 50 rows + count per table).
    • Inlines CSS, fonts, Chart.js, and the chart-app JS into a single HTML file.
    • Writes output/dashboard.html and a small meta file at /tmp/dashboard_meta.json (used by the Telegram step).

    If any vendor file is missing, the script stops with a clear message. Run python3 scripts/bundle-assets.py once to fix.

  2. Send to Telegram. Delivery lives in one committed, allowlisted command so the unattended daily claude -p run can run it without per-call approval (it can't build the read-secret + curl send inline — the permission analyzer won't auto-approve a command that sources .secrets and expands ${bot_token}, and the Write tool isn't granted unattended). The token is read at runtime and never printed.

    scripts/send_telegram.sh            # add: --note "<line>" to append a caption line
    

    What it does (= the old steps 2+3, now deterministic):

    • Sends output/dashboard.html as a document, caption Finance — <AS_OF_DATE> · <net worth> (literal · U+00B7), read from /tmp/dashboard_meta.json.
    • If data/last_sync_summary.md exists, sends it as a second sendMessage (HTML parse mode; bold title Sync · <AS_OF_DATE>; split into ≤3900-char parts on \n boundaries; ## Ingested/## Triaged headers render as bold New/Filed, any other ## header — e.g. ## ⚠️ Warnings — passes through as its own bold line), then deletes it on success. The summary may lead with a ⚠️ Warnings block — that's expected on degraded runs, not an error. Absent → prints Sync summary: Skipped (no summary).
    • Telegram not configured (no [telegram] in .secrets/findash) → prints Telegram delivery skipped: … and exits 0 (local file still useful). Never deletes the local dashboard on a Telegram failure.

    Pass --note "<line>" to append a caption line — the morning flow uses this to surface a best-effort fetch failure. The script prints Sent to chat <id> / Telegram delivery failed: <description> / the Sync summary: … line — relay them in step 3.

  3. Report. Print:

    • The absolute path of output/dashboard.html.
    • The Telegram delivery status: Sent to chat <chat_id>, Telegram delivery skipped: …, or Telegram delivery failed: <description>.
    • The sync summary delivery status: Sync summary: Sent (<N> bullets), Sync summary: Skipped (no summary), or Sync summary: Failed: <description>.
    • Any tickers Yahoo couldn't price (the script logs them on FAILED: — flag them so the user knows which positions fell back to cost basis).

Where judgment still lives (not in the script)

  • Deciding whether a fresh balance figure looks plausible or whether a sync mis-parsed something. If a number looks wrong, check the source doc and explain rather than rendering a broken figure (e.g. a closed Hapoalim sub-account showing an apparent negative balance from a parser artifact when the real closing balance was 0).
  • Whether to mention a particular caveat in the Overview footnote (e.g. "no price for X" or "this account was just opened").
  • The contents of the Telegram caption when the dashboard contains something unusual.

Principles

  • Don't invent design. All visual choices are in styles.css and the template. Don't add inline styles, classes, or markup not already defined.
  • Be honest with empty states. If a section has no data yet, show a brief italic muted note ("No payslips yet"), not a fake placeholder row.
  • Number formatting: group thousands; 2 decimals for amounts <10,000, 0 decimals for ≥10,000. Right-align money columns.
  • Hebrew text passes through unchanged. dir="auto" on table cells is already handled by the script.
  • The "SQLite data" tab is for debugging. Show raw rows truthfully. Don't reformat or hide columns.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most finance skills give in ~1.5k tokens

Counted across 469 of the 469 authors here whose files we hold, read 2026-08-07

  • Extract date vendor amount and descriptionin 15 of 469, across 3 files
  • Scan folder for invoice filesin 14 of 469, across 2 files
  • Rename files to standard formatin 14 of 469, across 2 files
  • Show organization plan before movingin 14 of 469, across 2 files
  • Generate summary CSVin 14 of 469, across 2 files
  • Organize files by categoryin 13 of 469, across 1 file
  • Preserve original filesin 13 of 469, across 1 file
  • Flag files missing critical infoin 13 of 469, across 1 file
  • Produce the requested output filein 9 of 469, across 4 files
  • Build best, base, and worst case scenariosin 9 of 469, across 5 files
  • Implement backoff if rate limit errors occurin 8 of 469, across 3 files
  • Determine the weighted average cost of capitalin 8 of 469, across 4 files

Said here and by no other author read

  • run the rendering script
  • send the dashboard via the delivery script
  • report the file path and delivery status
  • flag any tickers lacking live prices
  • check the source doc if a figure looks wrong
  • explain implausible figures instead of rendering them

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.