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.
- package/.github/workflows/publish.yml +27 -0
- package/CLAUDE.md +73 -0
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/__mocks__/@google-cloud/local-auth.js +11 -0
- package/__mocks__/googleapis.js +42 -0
- package/eslint.config.js +75 -0
- package/images/banner.png +0 -0
- package/package.json +12 -2
- package/src/cli.js +416 -7
- package/src/deletion-log.js +21 -4
- package/src/gmail-auth.js +88 -10
- package/src/gmail-monitor.js +29 -4
- package/src/state.js +5 -4
- package/src/types.js +45 -0
- package/src/utils.js +30 -0
- package/tests/analyze.test.js +165 -0
- package/tests/deletion-log.test.js +171 -0
- package/tests/gmail-auth.test.js +77 -0
- package/tests/gmail-monitor.test.js +135 -0
- package/tests/notifier.test.js +27 -0
- package/tests/setup.js +16 -0
- package/tests/setup.test.js +214 -0
- package/tests/state-multiacccount.test.js +91 -0
- package/tests/state.test.js +66 -0
- package/vitest.config.js +13 -0
- package/com.danielparedes.inboxd.plist +0 -40
- package/credentials.json +0 -1
|
@@ -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
|
+
[](https://www.npmjs.com/package/inboxd)
|
|
4
|
+
[](https://www.npmjs.com/package/inboxd)
|
|
5
|
+
[](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
|
+

|
|
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,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
|
+
};
|
package/eslint.config.js
ADDED
|
@@ -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.
|
|
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
|
}
|