Skip to content

Installer: --help prints usage, unknown options refused - #143

Merged
marcodonghiaa merged 37 commits into
mainfrom
claude/project-thread-mj17ax
Nov 13, 2026
Merged

marcodonghiaa merged 37 commits into
mainfrom
claude/project-thread-mj17ax

Conversation

@marcodonghiaa

Copy link
Copy Markdown
Owner

Closes #132.

Before this change, any first argument was taken as the install folder, so npx create-alopex --help started installing into ./--help.

  • New lib.parseArgs:
    • -h and --help print usage and exit 0.
    • Any other word starting with - gives "Unknown option …" plus usage, and exits 1.
    • A second argument is refused.
    • Otherwise the argument is the folder (default alopex).
  • installer/README.md lists --help.

Tests

  • npm test: 360/360. New parseArgs test, which fails without the fix.
  • Ran by hand: node installer/index.js --help exits 0 and --nope exits 1; neither creates a folder.

No migration, no function change.


Generated by Claude Code

…match pg_cron

- markRefunds (Deno post-sync and Node classify-flow) pairs only rows whose flow_source is
  'default', guarded on it too: a flow you, a rule or a past choice decided is never moved
  to refunded.
- Node sync stores own_counterparty like the Deno sync (same IBAN compare, left out when
  your accounts can't be read).
- Installer: Gemini privacy note says what goes to Google (names, descriptions, amounts,
  imported PDFs) and the free-tier terms.
- README: sync runs in Supabase (pg_cron + Edge Functions), not on your computer.
- package.json: name alopex, real description, version 0.1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Legacy flows (set before flow_source existed) are what refund pairing always read, so a
refund of a charge from before the upgrade still pairs. Only flows you or a rule decided
stay untouched. Comments no longer claim the dashboard can mark refunds by hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
A "not a transfer" flow rule sets flow_source='rule' but keeps the
direction, so the default/legacy-only filter stopped pairing refunds for
those merchants (counted as spend and income). Refunds now skip only
flows set by hand. The update guards flow_type too (new optional alsoIn
in applyGroupedUpdates), so a row a rule turned into a transfer after
the read is left alone. Tests now run against an in-memory table and
check which rows pair, not the query shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
entry_reference is not unique across accounts, so pages could overlap
or skip rows and miss a pair. The Deno side already does this.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
A pair whose second write failed, or whose other side you moved to
Transfer or deleted, stayed 'refunded' on one side for good, putting
spend and income off by the amount. Each run now repairs these first:
it finishes a pair whose charge is still plain spend, counts a lone
credit as income again (keeping refund_of, so it can only re-pair with
that same charge, never last month's identical one), and counts a
charge with no live refunded credit as spend again so it pairs anew.
Rows you set by hand are never touched. A credit looks its charge up
by key with no date limit, so pairs at the window edge stay intact.

Also: candidates are read in primary-key order and deduped by key (a
concurrent write could shift a row into two pages), and a failed refund
write now marks the post-sync run as failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
While the Node scheduler still runs, it could pair a credit the Edge
repair reset to income with an older identical charge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
restrict_transaction_updates now guards refund_of too. Only the refund
pairing (service role, trigger skipped) writes it; a signed-in user
setting it could break the pairing query for every user or pair a
credit with any charge (P2-3).

Test: lock-refund-of-migration.test.js "a signed-in user cannot change
refund_of" (also checked on PGlite: user update rejected, service role
and category/flow updates still allowed, rollback reopens it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
A charge lookup that errors now skips that account's repair for the
run (counted as failed, logged by code only) instead of throwing out of
markRefunds, which skipped refunds for every user (also P2-2).

Test: flow.test.ts "a failed charge lookup on one account is counted,
the others still repair and pair".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
`node --test installer/` also ran installer/index.js on Node 22 (real install + Supabase call).
Test: "the installer test command runs only the test files".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Subscription/One-time runs right after categories, not last.
Test: "the README lists the post-sync steps in the order they run".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ions

post-sync also sends Splitwise expense descriptions to Gemini (categorizeSplitwise).
Test: "both Gemini privacy notes mention Splitwise".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Up/down/up in one rolled-back transaction: a signed-in user can't change or clear refund_of,
still edits category/flow, can't touch other users' rows; the service role still writes it.
Fails against the migration without the lock line (checked on local Postgres 16).
Test: "a rehearsal runs the lock as a signed-in user and as the service role".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
npx create-alopex downloads tag v<installer version>; it was still v0.1.0, so new installs missed
13 migrations. UPGRADING.md gets a v0.2.0 section (installer and manual upgrade order) and the
refund_of note now says post-sync must be redeployed too.
Test: "UPGRADING.md has a section for the installer version".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…changelog

FAQ (and its JSON-LD) said Gemini sees transaction descriptions; it also gets names, amounts,
Splitwise descriptions and imported PDFs, and the free tier may train on them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Before, any first argument was the install folder, so --help installed into ./--help.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
@vercel

vercel Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
myfinances Ready Ready Preview Nov 13, 2026 9:33pm UTC

@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8fcc6f9d-dad2-492b-b16e-c258d86d95c3
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

… (polish-1 B1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…arting with - (polish-1 B2/B3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
On Windows cmd expands %VAR% even inside quotes, so tar -C would unpack elsewhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… in lib (polish-3 F9, F11)

main() now only applies lib.startup(argv), so help/refuse/install is covered without
spawning the installer (a spawn test would start a real install if it broke).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…alopex/alopex (polish-5 I1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ide the install; mark Codespaces-only steps (polish-5 I1, I2, I5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ish-5 I1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… it too (polish-5 I1 re-audit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ding (polish-5 I5 re-audit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…r, after asking (polish-5 I1 re-audit 2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… (polish-5 I1 re-audit nit)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
@marcodonghiaa
marcodonghiaa merged commit 42ba6e6 into main Nov 13, 2026
7 checks passed
@marcodonghiaa marcodonghiaa mentioned this pull request Nov 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Installer: --help is taken as the folder name

2 participants