ray-finance 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/.claude/settings.local.json +16 -0
  2. package/.env.example +13 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +19 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +9 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +5 -0
  6. package/.github/workflows/ci.yml +21 -0
  7. package/CHANGELOG.md +16 -0
  8. package/CODE_OF_CONDUCT.md +31 -0
  9. package/CONTRIBUTING.md +41 -0
  10. package/Dockerfile +8 -0
  11. package/LICENSE +21 -0
  12. package/README.md +168 -0
  13. package/SECURITY.md +36 -0
  14. package/SPEC.md +374 -0
  15. package/dist/ai/agent.d.ts +2 -0
  16. package/dist/ai/agent.js +80 -0
  17. package/dist/ai/audit.d.ts +3 -0
  18. package/dist/ai/audit.js +6 -0
  19. package/dist/ai/context.d.ts +6 -0
  20. package/dist/ai/context.js +89 -0
  21. package/dist/ai/insights.d.ts +3 -0
  22. package/dist/ai/insights.js +378 -0
  23. package/dist/ai/memory.d.ts +14 -0
  24. package/dist/ai/memory.js +12 -0
  25. package/dist/ai/redactor.d.ts +2 -0
  26. package/dist/ai/redactor.js +92 -0
  27. package/dist/ai/system-prompt.d.ts +2 -0
  28. package/dist/ai/system-prompt.js +85 -0
  29. package/dist/ai/tools.d.ts +4 -0
  30. package/dist/ai/tools.js +695 -0
  31. package/dist/alerts/index.d.ts +11 -0
  32. package/dist/alerts/index.js +95 -0
  33. package/dist/auth/anthropic.d.ts +7 -0
  34. package/dist/auth/anthropic.js +85 -0
  35. package/dist/auth/pkce.d.ts +5 -0
  36. package/dist/auth/pkce.js +10 -0
  37. package/dist/auth/store.d.ts +12 -0
  38. package/dist/auth/store.js +51 -0
  39. package/dist/cli/backup.d.ts +2 -0
  40. package/dist/cli/backup.js +85 -0
  41. package/dist/cli/chat.d.ts +1 -0
  42. package/dist/cli/chat.js +97 -0
  43. package/dist/cli/commands.d.ts +13 -0
  44. package/dist/cli/commands.js +201 -0
  45. package/dist/cli/format.d.ts +12 -0
  46. package/dist/cli/format.js +119 -0
  47. package/dist/cli/index.d.ts +2 -0
  48. package/dist/cli/index.js +176 -0
  49. package/dist/cli/scheduler.d.ts +2 -0
  50. package/dist/cli/scheduler.js +114 -0
  51. package/dist/cli/setup.d.ts +1 -0
  52. package/dist/cli/setup.js +168 -0
  53. package/dist/config.d.ts +22 -0
  54. package/dist/config.js +60 -0
  55. package/dist/daily-sync.d.ts +7 -0
  56. package/dist/daily-sync.js +94 -0
  57. package/dist/db/connection.d.ts +5 -0
  58. package/dist/db/connection.js +37 -0
  59. package/dist/db/encryption.d.ts +3 -0
  60. package/dist/db/encryption.js +24 -0
  61. package/dist/db/helpers.d.ts +16 -0
  62. package/dist/db/helpers.js +45 -0
  63. package/dist/db/schema.d.ts +2 -0
  64. package/dist/db/schema.js +194 -0
  65. package/dist/index.d.ts +1 -0
  66. package/dist/index.js +1 -0
  67. package/dist/plaid/client.d.ts +2 -0
  68. package/dist/plaid/client.js +22 -0
  69. package/dist/plaid/link.d.ts +8 -0
  70. package/dist/plaid/link.js +23 -0
  71. package/dist/plaid/sync.d.ts +18 -0
  72. package/dist/plaid/sync.js +186 -0
  73. package/dist/public/link.html +161 -0
  74. package/dist/queries/index.d.ts +163 -0
  75. package/dist/queries/index.js +411 -0
  76. package/dist/scoring/index.d.ts +53 -0
  77. package/dist/scoring/index.js +375 -0
  78. package/dist/server.d.ts +7 -0
  79. package/dist/server.js +140 -0
  80. package/docker-compose.yml +9 -0
  81. package/package.json +55 -0
  82. package/site/next-env.d.ts +6 -0
  83. package/site/next.config.ts +7 -0
  84. package/site/package-lock.json +1661 -0
  85. package/site/package.json +24 -0
  86. package/site/postcss.config.mjs +7 -0
  87. package/site/public/favicon.png +0 -0
  88. package/site/public/ray-og.jpg +0 -0
  89. package/site/public/robots.txt +4 -0
  90. package/site/public/sitemap.xml +8 -0
  91. package/site/src/app/copy-command.tsx +30 -0
  92. package/site/src/app/globals.css +87 -0
  93. package/site/src/app/layout.tsx +64 -0
  94. package/site/src/app/page.tsx +841 -0
  95. package/site/src/app/pii-scramble.tsx +190 -0
  96. package/site/src/app/reveal.tsx +29 -0
  97. package/site/tsconfig.json +21 -0
  98. package/src/ai/agent.ts +106 -0
  99. package/src/ai/audit.ts +11 -0
  100. package/src/ai/context.ts +93 -0
  101. package/src/ai/insights.ts +474 -0
  102. package/src/ai/memory.ts +21 -0
  103. package/src/ai/redactor.ts +102 -0
  104. package/src/ai/system-prompt.ts +90 -0
  105. package/src/ai/tools.ts +716 -0
  106. package/src/alerts/index.ts +123 -0
  107. package/src/cli/backup.ts +113 -0
  108. package/src/cli/chat.ts +105 -0
  109. package/src/cli/commands.ts +240 -0
  110. package/src/cli/format.ts +149 -0
  111. package/src/cli/index.ts +193 -0
  112. package/src/cli/scheduler.ts +116 -0
  113. package/src/cli/setup.ts +189 -0
  114. package/src/config.ts +81 -0
  115. package/src/daily-sync.ts +155 -0
  116. package/src/db/connection.ts +38 -0
  117. package/src/db/encryption.ts +29 -0
  118. package/src/db/helpers.ts +47 -0
  119. package/src/db/schema.ts +196 -0
  120. package/src/index.ts +3 -0
  121. package/src/plaid/client.ts +25 -0
  122. package/src/plaid/link.ts +25 -0
  123. package/src/plaid/sync.ts +219 -0
  124. package/src/public/link.html +161 -0
  125. package/src/queries/index.ts +586 -0
  126. package/src/scoring/index.ts +468 -0
  127. package/src/server.ts +162 -0
  128. package/tsconfig.json +16 -0
@@ -0,0 +1,16 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(npm install:*)",
5
+ "Bash(gh api:*)",
6
+ "mcp__paper__create_artboard",
7
+ "mcp__paper__write_html",
8
+ "mcp__paper__get_screenshot",
9
+ "mcp__paper__delete_nodes",
10
+ "Bash(npx next:*)",
11
+ "Bash(npx tsc:*)",
12
+ "Bash(git add:*)",
13
+ "Bash(git commit:*)"
14
+ ]
15
+ }
16
+ }
package/.env.example ADDED
@@ -0,0 +1,13 @@
1
+ # Anthropic API key for AI chat — https://console.anthropic.com
2
+ ANTHROPIC_API_KEY=
3
+
4
+ # Plaid credentials for bank sync — https://dashboard.plaid.com
5
+ PLAID_CLIENT_ID=
6
+ PLAID_SECRET=
7
+ PLAID_ENV=production
8
+
9
+ # Database encryption key (any strong passphrase)
10
+ DB_ENCRYPTION_KEY=
11
+
12
+ # Separate key for encrypting stored Plaid access tokens (any strong passphrase)
13
+ PLAID_TOKEN_SECRET=
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: Bug Report
3
+ about: Report a bug
4
+ labels: bug
5
+ ---
6
+
7
+ **What happened?**
8
+
9
+ **What did you expect?**
10
+
11
+ **Steps to reproduce**
12
+ 1.
13
+ 2.
14
+ 3.
15
+
16
+ **Environment**
17
+ - OS:
18
+ - Node.js version:
19
+ - Ray version (`ray --version`):
@@ -0,0 +1,9 @@
1
+ ---
2
+ name: Feature Request
3
+ about: Suggest a feature
4
+ labels: enhancement
5
+ ---
6
+
7
+ **What problem does this solve?**
8
+
9
+ **Describe the solution you'd like**
@@ -0,0 +1,5 @@
1
+ ## What
2
+
3
+ ## Why
4
+
5
+ ## Test plan
@@ -0,0 +1,21 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ node-version: [18, 20, 22]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: ${{ matrix.node-version }}
20
+ - run: npm install
21
+ - run: npm run build
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ Initial open source release.
6
+
7
+ - CLI interface with 13 commands (`ray`, `setup`, `sync`, `link`, `status`, `transactions`, `spending`, `budgets`, `goals`, `score`, `alerts`, `export`, `import`)
8
+ - AI financial advisor powered by Claude with 13+ tools
9
+ - Plaid integration for bank sync (checking, savings, credit cards, investments, loans)
10
+ - Encrypted local SQLite database (AES-256)
11
+ - Daily financial scoring (0-100) with streaks and 14 achievements
12
+ - Budget tracking with overage alerts
13
+ - Financial goal tracking
14
+ - Transaction auto-recategorization via user-defined rules
15
+ - Conversation memory and persistent financial context
16
+ - Data export/import for backup and restore
@@ -0,0 +1,31 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to a positive environment:
10
+
11
+ - Being respectful of differing viewpoints and experiences
12
+ - Giving and gracefully accepting constructive feedback
13
+ - Focusing on what is best for the community
14
+ - Showing empathy towards other community members
15
+
16
+ Examples of unacceptable behavior:
17
+
18
+ - Trolling, insulting/derogatory comments, and personal or political attacks
19
+ - Public or private harassment
20
+ - Publishing others' private information without explicit permission
21
+ - Other conduct which could reasonably be considered inappropriate in a professional setting
22
+
23
+ ## Enforcement
24
+
25
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project maintainer at clark@rayfinance.app.
26
+
27
+ All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
28
+
29
+ ## Attribution
30
+
31
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
@@ -0,0 +1,41 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in contributing to Ray.
4
+
5
+ ## Development Setup
6
+
7
+ ```bash
8
+ git clone https://github.com/clarkdinnison/ray-finance.git
9
+ cd ray-finance
10
+ npm install
11
+ npm run build
12
+ npm link
13
+ ```
14
+
15
+ You'll need Plaid and Anthropic API keys to test. Copy `.env.example` to `.env` and fill in your credentials.
16
+
17
+ ## Making Changes
18
+
19
+ 1. Fork the repo and create a branch from `main`
20
+ 2. Make your changes
21
+ 3. Run `npm run build` to verify the project compiles
22
+ 4. Open a pull request
23
+
24
+ ## Code Style
25
+
26
+ - TypeScript with strict mode
27
+ - ES modules (`"type": "module"`)
28
+ - Prefer simple, direct code over abstractions
29
+ - No unnecessary dependencies
30
+
31
+ ## Reporting Bugs
32
+
33
+ Open a GitHub issue with:
34
+ - What you expected to happen
35
+ - What actually happened
36
+ - Steps to reproduce
37
+ - Your Node.js version and OS
38
+
39
+ ## Security Issues
40
+
41
+ See [SECURITY.md](SECURITY.md) for reporting security vulnerabilities. Do not open public issues for security bugs.
package/Dockerfile ADDED
@@ -0,0 +1,8 @@
1
+ FROM node:20-slim
2
+ WORKDIR /app
3
+ COPY package*.json ./
4
+ RUN npm ci --production
5
+ COPY dist/ ./dist/
6
+ COPY src/public/ ./dist/public/
7
+ EXPOSE 3000
8
+ CMD ["node", "dist/index.js"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Clark Dinnison
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # Ray
2
+
3
+ An open-source CLI that connects to your bank and already knows your finances before you ask.
4
+
5
+ ```
6
+ Friday, Mar 28
7
+
8
+ net worth $45,230 +$120
9
+
10
+ spending $2,340 this month · $340 less vs last month
11
+ Dining -$114 · Shopping -$142 · Groceries -$73
12
+
13
+ ▓▓▓▓▓▓▓░ Dining 92%
14
+
15
+ ▓▓▓▓░░░░ Emergency fund $18,200/$40,000
16
+
17
+ upcoming Netflix $16 in 3d · Comcast $142 in 6d
18
+
19
+ score 72/100 · 5d no dining · 3d on pace
20
+
21
+ ──────────────────────────────────────────────────
22
+
23
+ ❯ if I quit my job to freelance, how long can I survive?
24
+
25
+ Based on your last 3 months: you burn $4,820/mo after
26
+ fixed costs. With $18,200 in savings, that's
27
+ 3.8 months of runway at current spend.
28
+
29
+ Cut dining and shopping to last-month levels and
30
+ you stretch to 5.1 months. Land one $8k contract
31
+ in that window and you never dip below $10k.
32
+ ```
33
+
34
+ Open Ray and it shows your net worth, spending vs last month, budget pacing, and upcoming bills — before you type a word. Ask a question and it answers from your real data, not guesses. Local-first. Encrypted. Open source.
35
+
36
+ ## Features
37
+
38
+ - **It already knows** — Every conversation starts with a real-time financial briefing. Net worth, spending velocity, budget alerts, goal pace, upcoming bills, and your daily score. No "let me look that up."
39
+ - **Bank sync via Plaid** — Connect checking, savings, credit cards, investments, and loans
40
+ - **Encrypted local database** — All data stays on your machine in an AES-256 encrypted SQLite database
41
+ - **Daily scoring** — A 0-100 behavior score with streaks and 14 unlockable achievements. No restaurants for a week? That's Kitchen Hero. Five zero-spend days? Monk Mode.
42
+ - **CFO personality** — Ray doesn't list options. It tells you what it would do and why, references your goals, and flags problems you haven't noticed yet.
43
+ - **Budgets and goals** — Track spending limits by category and progress toward financial goals
44
+ - **PII masking** — Names, account numbers, and identifying details are scrubbed before anything reaches the AI. Your data is analyzed, not exposed.
45
+ - **Smart alerts** — Large transactions, low balances, budget overruns
46
+ - **Auto-recategorization** — Define rules to automatically re-label transactions
47
+ - **Scheduled daily sync** — Automatic bank sync via launchd (macOS) or cron (Linux)
48
+ - **Export/import** — Back up and restore your financial data
49
+
50
+ ## Quick Start
51
+
52
+ ```bash
53
+ npx ray-finance setup
54
+ ```
55
+
56
+ The setup wizard offers two modes:
57
+
58
+ ### Quick setup (managed)
59
+
60
+ We handle the API keys. Your data stays local. $10/mo.
61
+
62
+ 1. Enter your name
63
+ 2. Get a Ray API key (opens Stripe checkout)
64
+ 3. Connect your bank
65
+ 4. Done — daily sync auto-scheduled at 6am
66
+
67
+ ### Self-hosted
68
+
69
+ Bring your own Anthropic and Plaid credentials. Free forever.
70
+
71
+ 1. Enter your Anthropic API key ([get one](https://console.anthropic.com))
72
+ 2. Enter your Plaid credentials ([get free keys](https://dashboard.plaid.com/signup))
73
+ 3. Connect your bank
74
+ 4. Done
75
+
76
+ ## Commands
77
+
78
+ | Command | Description |
79
+ |---------|-------------|
80
+ | `ray` | Interactive AI chat with your financial advisor |
81
+ | `ray setup` | Configure API keys and preferences |
82
+ | `ray link` | Connect a new bank account |
83
+ | `ray sync` | Pull latest transactions and balances |
84
+ | `ray status` | Quick financial dashboard |
85
+ | `ray transactions` | Recent transactions (filterable by category, merchant) |
86
+ | `ray spending [period]` | Spending breakdown by category |
87
+ | `ray budgets` | Budget status and overruns |
88
+ | `ray goals` | Financial goal progress |
89
+ | `ray score` | Daily score, streaks, and achievements |
90
+ | `ray alerts` | Active financial alerts |
91
+ | `ray export [path]` | Export data to a backup file |
92
+ | `ray import <path>` | Restore from a backup file |
93
+ | `ray billing` | Manage your Ray subscription (managed mode only) |
94
+
95
+ ## How It Works
96
+
97
+ ```
98
+ Checking · Savings · Credit · Investments · Loans · Mortgage
99
+
100
+ Plaid API
101
+
102
+ ┌──────────▼──────────┐
103
+ │ Local SQLite DB │
104
+ │ (AES-256 encrypted) │
105
+ └──────────┬──────────┘
106
+
107
+ ┌──────────▼──────────┐
108
+ │ ray CLI │
109
+ │ insights · tools │
110
+ │ scoring · alerts │
111
+ └──────────┬──────────┘
112
+
113
+ ┌─────────┴─────────┐
114
+ │ │
115
+ You (terminal) Claude API (PII-masked)
116
+ ```
117
+
118
+ Two outbound calls: Plaid (bank sync) and Anthropic (AI chat, PII-masked). Your financial data is never stored off your machine. No telemetry. No analytics.
119
+
120
+ ## Security & Privacy
121
+
122
+ - All financial data stored locally in `~/.ray/data/finance.db`
123
+ - Database encrypted with AES-256 (SQLCipher)
124
+ - Plaid access tokens encrypted at rest with AES-256-GCM
125
+ - Config file stored with `0600` permissions
126
+ - PII redacted before sending to Claude API
127
+ - No data leaves your machine — only API calls to Plaid and Anthropic
128
+
129
+ ## Configuration
130
+
131
+ Ray stores everything in `~/.ray/`:
132
+
133
+ ```
134
+ ~/.ray/
135
+ config.json # API keys and preferences (0600 permissions)
136
+ context.md # Persistent financial context for AI
137
+ data/
138
+ finance.db # Encrypted SQLite database
139
+ sync.log # Daily sync output
140
+ ```
141
+
142
+ ### Environment Variables
143
+
144
+ You can also configure Ray via environment variables or a `.env` file:
145
+
146
+ ```bash
147
+ ANTHROPIC_API_KEY= # Anthropic API key for AI chat
148
+ PLAID_CLIENT_ID= # Plaid client ID
149
+ PLAID_SECRET= # Plaid secret key
150
+ PLAID_ENV=production # Plaid environment
151
+ DB_ENCRYPTION_KEY= # Database encryption key
152
+ PLAID_TOKEN_SECRET= # Key for encrypting stored Plaid tokens
153
+ RAY_API_KEY= # Ray API key (managed mode, replaces the above)
154
+ ```
155
+
156
+ ## Development
157
+
158
+ ```bash
159
+ git clone https://github.com/clarkdinnison/ray-finance.git
160
+ cd ray-finance
161
+ npm install
162
+ npm run build
163
+ npm link # Makes 'ray' available globally
164
+ ```
165
+
166
+ ## License
167
+
168
+ MIT
package/SECURITY.md ADDED
@@ -0,0 +1,36 @@
1
+ # Security
2
+
3
+ ## Architecture
4
+
5
+ Ray is local-first. All financial data is stored on your machine in an encrypted SQLite database. No data is sent to Ray servers because there are no Ray servers.
6
+
7
+ ### Encryption
8
+
9
+ - **Database encryption**: The SQLite database is encrypted at rest using AES-256 via [SQLCipher](https://www.zetetic.net/sqlcipher/) (better-sqlite3-multiple-ciphers). The encryption key is provided during setup and stored in your local config.
10
+ - **Plaid token encryption**: Plaid access tokens are encrypted separately using AES-256-GCM with scrypt key derivation before being stored in the database.
11
+ - **File permissions**: Config and database files are created with `0600` permissions (owner read/write only).
12
+
13
+ ### Data Flow
14
+
15
+ Ray makes outbound API calls to three services:
16
+
17
+ | Service | Purpose | When |
18
+ |---------|---------|------|
19
+ | Plaid | Sync bank transactions and balances | `ray sync`, `ray link` |
20
+ | Anthropic | AI-powered chat responses | `ray` (interactive chat) |
21
+
22
+ No telemetry, analytics, or usage data is collected or transmitted.
23
+
24
+ ### PII Handling
25
+
26
+ When sending data to the Anthropic API for AI chat, Ray redacts personally identifiable information (account numbers, routing numbers) before transmission and restores it in the response for display.
27
+
28
+ ## Reporting a Vulnerability
29
+
30
+ If you discover a security vulnerability, please report it responsibly:
31
+
32
+ 1. **Do not** open a public GitHub issue
33
+ 2. Email **clark@rayfinance.app** with details
34
+ 3. Include steps to reproduce if possible
35
+
36
+ I will respond within 48 hours and work with you to address the issue before any public disclosure.