From points-activity
Extract Bilt Rewards (Bilt Mastercard / Bilt points) account activity into the unified points-activity CSV (Date, Description, Amount) plus the current balance. Use whenever the user wants to pull, export, check, sync, or monitor their Bilt points history, rewards activity, earnings, or point transfers/redemptions to partners (World of Hyatt, American/AAdvantage, Alaska/Atmos, Accor, Flying Blue, British Airways/Avios, etc.) — including recurring/scheduled monthly checks. Triggers on "get my Bilt points", "update my Bilt activity", "Bilt rewards history", "Bilt Mastercard points". Part of the points-activity skill suite; uses Bilt's JSON API (full history). Requires the user to be logged in to bilt.com in the connected Chrome browser.
How this skill is triggered — by the user, by Claude, or both
Slash command
/points-activity:bilt-activityThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Unified output contract.** Part of the `points-activity` suite. `scripts/transform.py`
Unified output contract. Part of the
points-activitysuite.scripts/transform.pywritesDate, Description, Amountand the filenamebilt_activity_<from>_<to>.csv(covered range) via the sharedscripts/activity_output.py, and printsBALANCE:/COVERED:/REQUESTED:/FILE:/ROWS:to stdout.
Bilt is a bank/card program: earnings are per-purchase (hundreds–thousands of rows), redemptions are point transfers out to airline/hotel partners. We collapse earnings hard (by month + benefit item) and keep redemptions per-transaction.
list_connected_browsers → select_browser).Endpoint: GET https://api.biltrewards.com/loyalty/activity?month=M&year=Y
with header authorization: Bearer <jwt> (the JWT is in localStorage — scan for a long
value starting with ey). Plain fetch(..., {credentials:'include'}) works.
Only month+year filter. limit, page, from/to, startDate/endDate are
all ignored (they return the default ~12 recent rows). So iterate months backward from the
current month until 3 consecutive empty months. Bilt has no history-window limit —
full account history is retrievable and reconciles to the balance.
tabs_context_mcp → navigate to https://www.bilt.com/rewards/activity.
Confirm login + a points balance in the header. Decline cookie banners. Keep tabId.scripts/fetch_activity.js — finds the token, iterates months, stashes
compacted entries on window.__biltall, returns {count, oldest, newest, balanceCheck}.
balanceCheck should equal the displayed balance.scripts/dump_console.js (emits BILT###~<json-array> chunks),
then read_console_messages(pattern:"^BILT\\d", limit:60, tabId:...). Reassemble the
chunks in order and concatenate the arrays into a single JSON array file (e.g.
/tmp/raw.json). (Large dumps: read in batches; chunks are ordered by their index.)python3 scripts/transform.py /tmp/raw.json <output_dir> [from] [to] [balance]
# from/to ISO yyyy-mm-dd or '-'; balance = header "pts" figure.
present_files on the CSV. Report balance + covered range.Compacted entry: {d, t (title/merchant), a (activity), s (pointState), tp (totalPoints), b: [{t (benefit item title), v (points int)}]}.
Spendable points = totalPoints, and sum(b[].v) == totalPoints (verified). The
benefit items in b are the per-line points (e.g. "2X Points on All Transactions",
"Additional 1X - Point Accelerator", "3x Points on Dining"). Cash-back "Earn Bilt Cash"
(+$…) and non-point benefits are dropped (the fetch script keeps only point-bearing
items — those whose value parses as a number, not a $ amount).
Classify by SIGN, not status text (robust to Bilt's vocabulary):
totalPoints < 0. Transfers to partners (World of
Hyatt, British Airways/Avios, Accor, Atmos, Flying Blue, …) and reversals/refunds.
Keep the real date, each entry its own row, description = the title.totalPoints >= 0. Explode into benefit items; move each to the
last day of its month; collapse by (month, item-title) summed across all
merchants — no merchant in the key. So every "3x Points on Dining" in a month
becomes a single row.Drop zero-amount rows after collapsing (status rows like "Earned Gold status" carry no points and disappear).
Full history is available, so sum(Amount) == current balance exactly (verified:
80,723 == 80.7k). If it doesn't reconcile, you likely stopped the month-iteration too
early (raise the empty-month threshold) rather than hitting a history limit.
Run as a local Cowork Scheduled Task (needs the user's real Chrome + live bilt.com session). The API token expires, so a stale session needs a fresh login. Because Bilt keeps full history, a monthly cadence never misses anything; save each run's dated CSV and diff to spot new activity. For incremental runs you can fetch only the current + previous month rather than the full backfill.
Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.
npx claudepluginhub lionisiam/points-activity --plugin points-activity