inboxd 1.0.13 → 1.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.
package/README.md CHANGED
@@ -30,7 +30,7 @@ npm install -g inboxd
30
30
  Run the interactive setup wizard:
31
31
 
32
32
  ```bash
33
- inbox setup
33
+ inboxd setup
34
34
  ```
35
35
 
36
36
  The wizard will guide you through:
@@ -60,33 +60,33 @@ mv ~/Downloads/client_secret_*.json ~/.config/inboxd/credentials.json
60
60
  ### 2. Authenticate
61
61
 
62
62
  ```bash
63
- inbox auth --account personal
63
+ inboxd auth --account personal
64
64
  ```
65
65
 
66
66
  ### 3. Check Your Inbox
67
67
 
68
68
  ```bash
69
- inbox summary
69
+ inboxd summary
70
70
  ```
71
71
 
72
72
  ## Commands
73
73
 
74
74
  | Command | Description |
75
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 delete --sender <pattern>` | Delete by sender (with confirmation) |
84
- | `inbox delete --match <pattern>` | Delete by subject (with confirmation) |
85
- | `inbox restore --last 1` | Restore last deleted email |
86
- | `inbox deletion-log` | View deletion history |
87
- | `inbox logout --all` | Remove all accounts |
88
- | `inbox install-service` | Install background monitoring (macOS) |
89
- | `inbox install-skill` | Install Claude Code skill for AI agents |
76
+ | `inboxd setup` | Interactive setup wizard |
77
+ | `inboxd auth -a <name>` | Authenticate a Gmail account |
78
+ | `inboxd accounts` | List configured accounts |
79
+ | `inboxd summary` | Show inboxd summary for all accounts |
80
+ | `inboxd check` | Check for new emails + send notifications |
81
+ | `inboxd check -q` | Silent check (for background use) |
82
+ | `inboxd delete --ids <ids>` | Move emails to trash |
83
+ | `inboxd delete --sender <pattern>` | Delete by sender (with confirmation) |
84
+ | `inboxd delete --match <pattern>` | Delete by subject (with confirmation) |
85
+ | `inboxd restore --last 1` | Restore last deleted email |
86
+ | `inboxd deletion-log` | View deletion history |
87
+ | `inboxd logout --all` | Remove all accounts |
88
+ | `inboxd install-service` | Install background monitoring (macOS) |
89
+ | `inboxd install-skill` | Install Claude Code skill for AI agents |
90
90
 
91
91
  ## Configuration
92
92
 
@@ -106,10 +106,10 @@ Install as a macOS launchd service to check for new emails periodically:
106
106
 
107
107
  ```bash
108
108
  # Install and start with default 5-minute interval
109
- inbox install-service
109
+ inboxd install-service
110
110
 
111
111
  # Or customize the interval
112
- inbox install-service --interval 10
112
+ inboxd install-service --interval 10
113
113
  ```
114
114
 
115
115
  The service starts automatically after installation. Manage it with:
@@ -127,7 +127,7 @@ launchctl unload ~/Library/LaunchAgents/com.danielparedes.inboxd.plist
127
127
 
128
128
  **Note:** `install-service` is macOS-only. For Linux, use cron:
129
129
  ```bash
130
- */5 * * * * /path/to/node /path/to/inbox check --quiet
130
+ */5 * * * * /path/to/node /path/to/inboxd check --quiet
131
131
  ```
132
132
 
133
133
  ## JSON Output
@@ -135,13 +135,13 @@ launchctl unload ~/Library/LaunchAgents/com.danielparedes.inboxd.plist
135
135
  For AI agent integration, use the `--json` flag:
136
136
 
137
137
  ```bash
138
- inbox summary --json
138
+ inboxd summary --json
139
139
  ```
140
140
 
141
141
  Or use the `analyze` command for structured output:
142
142
 
143
143
  ```bash
144
- inbox analyze --count 20
144
+ inboxd analyze --count 20
145
145
  ```
146
146
 
147
147
  ## AI Agent Integration
@@ -163,12 +163,12 @@ This package includes a **skill** that can be installed globally, enabling any C
163
163
  After installing inboxd, run:
164
164
 
165
165
  ```bash
166
- inbox install-skill
166
+ inboxd install-skill
167
167
  ```
168
168
 
169
169
  This copies the inbox-assistant skill to `~/.claude/skills/`, making it available in all your Claude Code sessions.
170
170
 
171
- The setup wizard (`inbox setup`) also offers to install the skill automatically.
171
+ The setup wizard (`inboxd setup`) also offers to install the skill automatically.
172
172
 
173
173
  ### What the Skill Enables
174
174
 
@@ -194,13 +194,13 @@ The skill auto-updates when you update inboxd (if already installed). You can al
194
194
 
195
195
  ```bash
196
196
  npm update -g inboxd
197
- inbox install-skill
197
+ inboxd install-skill
198
198
  ```
199
199
 
200
200
  Safety features:
201
201
  - Won't overwrite skills not created by inboxd (uses `source: inboxd` marker)
202
202
  - Creates `SKILL.md.backup` before replacing if you've modified the skill
203
- - Use `inbox install-skill --force` to override ownership check
203
+ - Use `inboxd install-skill --force` to override ownership check
204
204
 
205
205
  ### CLI vs MCP
206
206
 
@@ -208,9 +208,9 @@ Unlike an MCP server that exposes raw Gmail API primitives, `inboxd` provides **
208
208
 
209
209
  | inboxd CLI | Raw Gmail MCP |
210
210
  |------------|---------------|
211
- | `inbox delete` logs before trashing | Just trashes |
212
- | `inbox restore` removes from log | Just untrashes |
213
- | `inbox analyze` formats for AI consumption | Raw API response |
211
+ | `inboxd delete` logs before trashing | Just trashes |
212
+ | `inboxd restore` removes from log | Just untrashes |
213
+ | `inboxd analyze` formats for AI consumption | Raw API response |
214
214
 
215
215
  The skill layer adds expert workflow guidance on top of these commands.
216
216
 
@@ -225,7 +225,7 @@ npm uninstall -g inboxd
225
225
  To also remove all account data and tokens:
226
226
 
227
227
  ```bash
228
- inbox logout --all
228
+ inboxd logout --all
229
229
  ```
230
230
 
231
231
  To completely remove all data including credentials:
@@ -239,13 +239,13 @@ rm -rf ~/.config/inboxd
239
239
  ## Troubleshooting
240
240
 
241
241
  **"credentials.json not found"**
242
- Run `inbox setup` or manually download OAuth credentials from Google Cloud Console and save to `~/.config/inboxd/credentials.json`.
242
+ Run `inboxd setup` or manually download OAuth credentials from Google Cloud Console and save to `~/.config/inboxd/credentials.json`.
243
243
 
244
244
  **"Token expired"**
245
245
  Delete the token file and re-authenticate:
246
246
  ```bash
247
247
  rm ~/.config/inboxd/token-<account>.json
248
- inbox auth -a <account>
248
+ inboxd auth -a <account>
249
249
  ```
250
250
 
251
251
  **No notifications appearing**
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "inboxd",
3
- "version": "1.0.13",
3
+ "version": "1.2.0",
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": {
7
- "inbox": "src/cli.js"
7
+ "inboxd": "src/cli.js"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
@@ -21,7 +21,7 @@
21
21
  "test": "vitest run",
22
22
  "test:watch": "vitest",
23
23
  "lint": "eslint src tests",
24
- "inbox": "node src/cli.js",
24
+ "inboxd": "node src/cli.js",
25
25
  "postinstall": "node scripts/postinstall.js || true"
26
26
  },
27
27
  "keywords": [
@@ -21,10 +21,10 @@ function showInstallHint() {
21
21
  │ inboxd installed successfully! │
22
22
  │ │
23
23
  │ Quick start: │
24
- inbox setup # First-time configuration │
24
+ inboxd setup # First-time configuration │
25
25
  │ │
26
26
  │ AI Agent Integration: │
27
- inbox install-skill # Enable Claude Code skill │
27
+ inboxd install-skill # Enable Claude Code skill │
28
28
  │ │
29
29
  │ This lets AI agents manage your inbox with expert triage. │
30
30
  │ │
@@ -50,7 +50,7 @@ function handleSkillUpdate() {
50
50
  // Someone else's skill with same name → don't touch, warn
51
51
  console.log(`\n⚠️ ~/.claude/skills/inbox-assistant exists but isn't from inboxd`);
52
52
  console.log(` The existing skill has source: "${status.source || 'none'}"`);
53
- console.log(` Run 'inbox install-skill --force' to replace it\n`);
53
+ console.log(` Run 'inboxd install-skill --force' to replace it\n`);
54
54
  return;
55
55
  }
56
56
 
@@ -69,13 +69,13 @@ function handleSkillUpdate() {
69
69
  }
70
70
  } else if (result.reason === 'backup_failed') {
71
71
  console.log(`\n⚠️ Could not backup existing skill - update skipped`);
72
- console.log(` Run 'inbox install-skill' manually to update\n`);
72
+ console.log(` Run 'inboxd install-skill' manually to update\n`);
73
73
  }
74
74
  }
75
75
  // Up-to-date → silent (no message)
76
76
  } catch (err) {
77
77
  // Fail silently - postinstall should not break npm install
78
- // User can always run 'inbox install-skill' manually
78
+ // User can always run 'inboxd install-skill' manually
79
79
  }
80
80
  }
81
81
 
@@ -0,0 +1,104 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { TOKEN_DIR } = require('./gmail-auth');
4
+ const { atomicWriteJsonSync } = require('./utils');
5
+
6
+ const LOG_DIR = TOKEN_DIR;
7
+ const LOG_FILE = path.join(LOG_DIR, 'archive-log.json');
8
+
9
+ /**
10
+ * Ensures the log directory exists
11
+ */
12
+ function ensureLogDir() {
13
+ if (!fs.existsSync(LOG_DIR)) {
14
+ fs.mkdirSync(LOG_DIR, { recursive: true });
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Reads the current archive log
20
+ * @returns {Array} Array of archive entries
21
+ */
22
+ function readArchiveLog() {
23
+ ensureLogDir();
24
+ if (!fs.existsSync(LOG_FILE)) {
25
+ return [];
26
+ }
27
+ try {
28
+ const content = fs.readFileSync(LOG_FILE, 'utf8');
29
+ return JSON.parse(content);
30
+ } catch (_err) {
31
+ return [];
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Logs archived emails to the archive log
37
+ * @param {Array} emails - Array of email objects with id, threadId, account, from, subject, snippet
38
+ */
39
+ function logArchives(emails) {
40
+ ensureLogDir();
41
+ const log = readArchiveLog();
42
+ const timestamp = new Date().toISOString();
43
+
44
+ for (const email of emails) {
45
+ log.push({
46
+ archivedAt: timestamp,
47
+ account: email.account,
48
+ id: email.id,
49
+ threadId: email.threadId,
50
+ from: email.from,
51
+ subject: email.subject,
52
+ snippet: email.snippet,
53
+ });
54
+ }
55
+
56
+ atomicWriteJsonSync(LOG_FILE, log);
57
+ }
58
+
59
+ /**
60
+ * Gets recent archives from the log
61
+ * @param {number} days - Number of days to look back (default: 30)
62
+ * @returns {Array} Array of archive entries within the time range
63
+ */
64
+ function getRecentArchives(days = 30) {
65
+ const log = readArchiveLog();
66
+ const cutoff = new Date();
67
+ cutoff.setDate(cutoff.getDate() - days);
68
+
69
+ return log.filter((entry) => {
70
+ const archivedAt = new Date(entry.archivedAt);
71
+ return archivedAt >= cutoff;
72
+ });
73
+ }
74
+
75
+ /**
76
+ * Gets the path to the log file (for display purposes)
77
+ * @returns {string} The log file path
78
+ */
79
+ function getArchiveLogPath() {
80
+ return LOG_FILE;
81
+ }
82
+
83
+ /**
84
+ * Removes entries from the archive log (e.g., after unarchiving)
85
+ * @param {Array<string>} ids - Array of message IDs to remove
86
+ */
87
+ function removeArchiveLogEntries(ids) {
88
+ ensureLogDir();
89
+ const log = readArchiveLog();
90
+
91
+ const newLog = log.filter(entry => !ids.includes(entry.id));
92
+
93
+ if (log.length !== newLog.length) {
94
+ atomicWriteJsonSync(LOG_FILE, newLog);
95
+ }
96
+ }
97
+
98
+ module.exports = {
99
+ logArchives,
100
+ getRecentArchives,
101
+ getArchiveLogPath,
102
+ readArchiveLog,
103
+ removeArchiveLogEntries,
104
+ };