inboxd 1.0.0 → 1.0.3

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.
@@ -0,0 +1,27 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: read
12
+ id-token: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-node@v4
17
+ with:
18
+ node-version: '20'
19
+ registry-url: 'https://registry.npmjs.org'
20
+
21
+ - run: npm ci
22
+
23
+ - run: npm test
24
+
25
+ - run: npm publish --provenance --access public
26
+ env:
27
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CLAUDE.md ADDED
@@ -0,0 +1,73 @@
1
+ # inboxd
2
+
3
+ CLI tool for Gmail monitoring with multi-account support and macOS notifications.
4
+
5
+ ## Quick Reference
6
+
7
+ ```bash
8
+ npm test # Run tests
9
+ npm run test:watch # Watch mode
10
+ inbox setup # First-time setup wizard
11
+ inbox auth -a <name> # Add account
12
+ inbox summary # Check all inboxes
13
+ inbox check -q # Background check
14
+ inbox install-service # Install launchd service (macOS only)
15
+ ```
16
+
17
+ ## Architecture
18
+
19
+ ```
20
+ src/
21
+ ├── cli.js # Entry point, command definitions (commander)
22
+ ├── gmail-auth.js # OAuth2 flow, token storage, multi-account management
23
+ ├── gmail-monitor.js # Gmail API: fetch, count, trash, restore
24
+ ├── state.js # Tracks seen emails per account
25
+ ├── deletion-log.js # Logs deleted emails for restore capability
26
+ └── notifier.js # macOS notifications (node-notifier)
27
+
28
+ tests/ # Vitest tests with mocked Google APIs
29
+ __mocks__/ # Manual mocks for googleapis, @google-cloud/local-auth
30
+ ```
31
+
32
+ ## Tech Stack
33
+
34
+ - **Runtime**: Node.js 18+ (CommonJS)
35
+ - **Gmail API**: `googleapis`, `@google-cloud/local-auth`
36
+ - **CLI**: `commander`
37
+ - **UI**: `chalk`, `boxen` (ESM packages, loaded via dynamic import)
38
+ - **Notifications**: `node-notifier`
39
+ - **Testing**: `vitest`
40
+
41
+ ## Data Storage
42
+
43
+ All user data lives in `~/.config/inboxd/`:
44
+
45
+ | File | Content |
46
+ |------|---------|
47
+ | `credentials.json` | OAuth client ID/secret from Google Cloud |
48
+ | `accounts.json` | `[{ name, email }]` for each linked account |
49
+ | `token-<name>.json` | OAuth refresh/access tokens |
50
+ | `state-<name>.json` | `{ seenEmailIds, lastCheck, lastNotifiedAt }` |
51
+ | `deletion-log.json` | Audit log for deleted emails |
52
+
53
+ ## Code Patterns
54
+
55
+ - **CommonJS** for all source files
56
+ - **Dynamic import** for ESM-only deps (`chalk`, `boxen`)
57
+ - **Functional style**, no classes
58
+ - **Retry with backoff** in `gmail-monitor.js` for API calls
59
+ - **Silent fail** for missing config files (returns defaults)
60
+
61
+ ## Key Behaviors
62
+
63
+ - `inbox setup` guides first-time users through credentials and auth
64
+ - `inbox check` marks emails as seen after notifying
65
+ - `inbox delete` logs to `deletion-log.json` before trashing
66
+ - `inbox restore` moves from Trash to Inbox, removes log entry
67
+ - `install-service` generates launchd plist dynamically (macOS only, warns on other platforms)
68
+
69
+ ## OAuth Notes
70
+
71
+ - Gmail API requires OAuth consent screen with test users for external accounts
72
+ - Tokens auto-refresh; delete token file to force re-auth
73
+ - Credentials can be in project root (dev) or `~/.config/inboxd/` (installed)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Paredes
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,164 @@
1
+ # Inboxd
2
+
3
+ [![npm version](https://img.shields.io/npm/v/inboxd.svg)](https://www.npmjs.com/package/inboxd)
4
+ [![npm downloads](https://img.shields.io/npm/dm/antigravity-claude-proxy.svg)](https://www.npmjs.com/package/inboxd)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ <a href="https://buymeacoffee.com/dparedesi" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50"></a>
8
+
9
+ A CLI tool for monitoring Gmail inboxes with multi-account support and macOS notifications.
10
+
11
+ ![VoxScriber Banner](images/banner.png)
12
+
13
+ ## Features
14
+
15
+ - **Multi-account support** - Monitor multiple Gmail accounts from one command
16
+ - **macOS notifications** - Get notified when new emails arrive
17
+ - **Background monitoring** - Run as a launchd service
18
+ - **Delete & restore** - Safely trash emails with undo capability
19
+ - **AI-ready output** - JSON mode for integration with AI agents
20
+ - **Interactive setup** - Guided wizard for first-time configuration
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install -g inboxd
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ Run the interactive setup wizard:
31
+
32
+ ```bash
33
+ inbox setup
34
+ ```
35
+
36
+ The wizard will guide you through:
37
+ 1. Opening Google Cloud Console to create OAuth credentials
38
+ 2. Validating and installing your credentials file
39
+ 3. Authenticating your first Gmail account
40
+
41
+ That's it! You're ready to go.
42
+
43
+ ## Manual Setup
44
+
45
+ If you prefer to set up manually:
46
+
47
+ ### 1. Get Gmail API Credentials
48
+
49
+ 1. Go to [Google Cloud Console](https://console.cloud.google.com/)
50
+ 2. Create a project and enable the **Gmail API**
51
+ 3. Configure OAuth consent screen (add yourself as test user)
52
+ 4. Create OAuth credentials (Desktop app)
53
+ 5. Download and save as `~/.config/inboxd/credentials.json`:
54
+
55
+ ```bash
56
+ mkdir -p ~/.config/inboxd
57
+ mv ~/Downloads/client_secret_*.json ~/.config/inboxd/credentials.json
58
+ ```
59
+
60
+ ### 2. Authenticate
61
+
62
+ ```bash
63
+ inbox auth --account personal
64
+ ```
65
+
66
+ ### 3. Check Your Inbox
67
+
68
+ ```bash
69
+ inbox summary
70
+ ```
71
+
72
+ ## Commands
73
+
74
+ | Command | Description |
75
+ |---------|-------------|
76
+ | `inbox setup` | Interactive setup wizard |
77
+ | `inbox auth -a <name>` | Authenticate a Gmail account |
78
+ | `inbox accounts` | List configured accounts |
79
+ | `inbox summary` | Show inbox summary for all accounts |
80
+ | `inbox check` | Check for new emails + send notifications |
81
+ | `inbox check -q` | Silent check (for background use) |
82
+ | `inbox delete --ids <ids>` | Move emails to trash |
83
+ | `inbox restore --last 1` | Restore last deleted email |
84
+ | `inbox deletion-log` | View deletion history |
85
+ | `inbox logout --all` | Remove all accounts |
86
+ | `inbox install-service` | Install background monitoring (macOS) |
87
+
88
+ ## Configuration
89
+
90
+ All configuration is stored in `~/.config/inboxd/`:
91
+
92
+ | File | Purpose |
93
+ |------|---------|
94
+ | `credentials.json` | Your OAuth client credentials |
95
+ | `accounts.json` | List of configured accounts |
96
+ | `token-<account>.json` | OAuth tokens per account |
97
+ | `state-<account>.json` | Seen email tracking per account |
98
+ | `deletion-log.json` | Record of deleted emails |
99
+
100
+ ## Background Monitoring
101
+
102
+ Install as a macOS launchd service to check for new emails periodically:
103
+
104
+ ```bash
105
+ # Install with default 5-minute interval
106
+ inbox install-service
107
+
108
+ # Or customize the interval
109
+ inbox install-service --interval 10
110
+ ```
111
+
112
+ Manage the service:
113
+
114
+ ```bash
115
+ # Check status
116
+ launchctl list | grep inboxd
117
+
118
+ # View logs
119
+ tail -f /tmp/inboxd.log
120
+
121
+ # Stop service
122
+ launchctl unload ~/Library/LaunchAgents/com.danielparedes.inboxd.plist
123
+ ```
124
+
125
+ **Note:** `install-service` is macOS-only. For Linux, use cron:
126
+ ```bash
127
+ */5 * * * * /path/to/node /path/to/inbox check --quiet
128
+ ```
129
+
130
+ ## JSON Output
131
+
132
+ For AI agent integration, use the `--json` flag:
133
+
134
+ ```bash
135
+ inbox summary --json
136
+ ```
137
+
138
+ Or use the `analyze` command for structured output:
139
+
140
+ ```bash
141
+ inbox analyze --count 20
142
+ ```
143
+
144
+ ## Troubleshooting
145
+
146
+ **"credentials.json not found"**
147
+ Run `inbox setup` or manually download OAuth credentials from Google Cloud Console and save to `~/.config/inboxd/credentials.json`.
148
+
149
+ **"Token expired"**
150
+ Delete the token file and re-authenticate:
151
+ ```bash
152
+ rm ~/.config/inboxd/token-<account>.json
153
+ inbox auth -a <account>
154
+ ```
155
+
156
+ **No notifications appearing**
157
+ Check macOS notification settings for Terminal/Node.js in System Preferences > Notifications.
158
+
159
+ **"install-service is only supported on macOS"**
160
+ The launchd service is macOS-specific. For other platforms, set up a cron job or scheduled task manually.
161
+
162
+ ## License
163
+
164
+ MIT
@@ -0,0 +1,11 @@
1
+ const { vi } = require('vitest');
2
+
3
+ module.exports = {
4
+ authenticate: vi.fn().mockResolvedValue({
5
+ credentials: {
6
+ refresh_token: 'mock-refresh-token',
7
+ access_token: 'mock-access-token',
8
+ expiry_date: Date.now() + 3600000
9
+ }
10
+ })
11
+ };
@@ -0,0 +1,42 @@
1
+ const { vi } = require('vitest');
2
+
3
+ const mockGmail = {
4
+ users: {
5
+ messages: {
6
+ list: vi.fn().mockResolvedValue({ data: { messages: [] } }),
7
+ get: vi.fn().mockResolvedValue({
8
+ data: {
9
+ id: '123',
10
+ threadId: 'thread123',
11
+ labelIds: ['INBOX'],
12
+ snippet: 'snippet',
13
+ payload: { headers: [] }
14
+ }
15
+ }),
16
+ trash: vi.fn().mockResolvedValue({ data: { id: '123', labelIds: ['TRASH'] } }),
17
+ untrash: vi.fn().mockResolvedValue({ data: { id: '123', labelIds: ['INBOX'] } }),
18
+ modify: vi.fn().mockResolvedValue({ data: { id: '123' } }),
19
+ },
20
+ labels: {
21
+ get: vi.fn().mockResolvedValue({ data: { messagesUnread: 5 } }),
22
+ list: vi.fn().mockResolvedValue({ data: { labels: [] } }),
23
+ },
24
+ getProfile: vi.fn().mockResolvedValue({ data: { emailAddress: 'test@example.com' } }),
25
+ }
26
+ };
27
+
28
+ const mockAuth = {
29
+ fromJSON: vi.fn().mockReturnValue({}),
30
+ OAuth2: vi.fn().mockImplementation(() => ({
31
+ generateAuthUrl: vi.fn().mockReturnValue('http://mock-auth-url'),
32
+ getToken: vi.fn().mockResolvedValue({ tokens: {} }),
33
+ setCredentials: vi.fn(),
34
+ })),
35
+ };
36
+
37
+ module.exports = {
38
+ google: {
39
+ gmail: vi.fn().mockReturnValue(mockGmail),
40
+ auth: mockAuth,
41
+ }
42
+ };
@@ -0,0 +1,75 @@
1
+ /** @type {import('eslint').Linter.Config[]} */
2
+ module.exports = [
3
+ {
4
+ files: ['src/**/*.js'],
5
+ languageOptions: {
6
+ ecmaVersion: 2022,
7
+ sourceType: 'commonjs',
8
+ globals: {
9
+ // Node.js globals
10
+ require: 'readonly',
11
+ module: 'readonly',
12
+ exports: 'readonly',
13
+ __dirname: 'readonly',
14
+ __filename: 'readonly',
15
+ process: 'readonly',
16
+ console: 'readonly',
17
+ Buffer: 'readonly',
18
+ setTimeout: 'readonly',
19
+ clearTimeout: 'readonly',
20
+ setInterval: 'readonly',
21
+ clearInterval: 'readonly',
22
+ },
23
+ },
24
+ rules: {
25
+ // Possible errors
26
+ 'no-undef': 'error',
27
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }],
28
+ 'no-constant-condition': 'error',
29
+ 'no-dupe-keys': 'error',
30
+ 'no-duplicate-case': 'error',
31
+ 'no-empty': ['error', { allowEmptyCatch: true }],
32
+ 'no-extra-semi': 'error',
33
+ 'no-unreachable': 'error',
34
+
35
+ // Best practices
36
+ 'eqeqeq': ['error', 'always', { null: 'ignore' }],
37
+ 'no-eval': 'error',
38
+ 'no-implied-eval': 'error',
39
+ 'no-return-await': 'error',
40
+ 'no-throw-literal': 'error',
41
+ 'prefer-promise-reject-errors': 'error',
42
+
43
+ // Style (minimal)
44
+ 'no-trailing-spaces': 'error',
45
+ 'semi': ['error', 'always'],
46
+ },
47
+ },
48
+ {
49
+ // Test files use ESM via vitest
50
+ files: ['tests/**/*.js', '**/*.test.js'],
51
+ languageOptions: {
52
+ ecmaVersion: 2022,
53
+ sourceType: 'module',
54
+ globals: {
55
+ describe: 'readonly',
56
+ it: 'readonly',
57
+ expect: 'readonly',
58
+ beforeEach: 'readonly',
59
+ afterEach: 'readonly',
60
+ beforeAll: 'readonly',
61
+ afterAll: 'readonly',
62
+ vi: 'readonly',
63
+ jest: 'readonly',
64
+ console: 'readonly',
65
+ process: 'readonly',
66
+ },
67
+ },
68
+ rules: {
69
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }],
70
+ },
71
+ },
72
+ {
73
+ ignores: ['node_modules/**', 'coverage/**', 'dist/**', '__mocks__/**'],
74
+ },
75
+ ];
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inboxd",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "CLI assistant for Gmail monitoring with multi-account support and AI-ready JSON output",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
@@ -10,9 +10,17 @@
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/dparedesi/inboxd.git"
12
12
  },
13
+ "bugs": {
14
+ "url": "https://github.com/dparedesi/inboxd/issues"
15
+ },
16
+ "homepage": "https://github.com/dparedesi/inboxd#readme",
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
13
20
  "scripts": {
14
21
  "test": "vitest run",
15
22
  "test:watch": "vitest",
23
+ "lint": "eslint src tests",
16
24
  "inbox": "node src/cli.js"
17
25
  },
18
26
  "keywords": [
@@ -35,9 +43,11 @@
35
43
  "chalk": "^5.6.2",
36
44
  "commander": "^14.0.2",
37
45
  "googleapis": "^169.0.0",
38
- "node-notifier": "^10.0.1"
46
+ "node-notifier": "^10.0.1",
47
+ "open": "^10.1.0"
39
48
  },
40
49
  "devDependencies": {
50
+ "eslint": "^9.39.2",
41
51
  "vitest": "^4.0.16"
42
52
  }
43
53
  }