agentrem 1.3.1 → 1.5.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 +121 -146
- package/assets/Agentrem.app/Contents/Info.plist +11 -0
- package/assets/Agentrem.app/Contents/MacOS/agentrem-notify +0 -0
- package/assets/notify-src/main.swift +159 -35
- package/dist/api.d.ts +93 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +111 -0
- package/dist/api.js.map +1 -0
- package/dist/notifier.d.ts +1 -0
- package/dist/notifier.d.ts.map +1 -1
- package/dist/notifier.js +2 -1
- package/dist/notifier.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/llms-full.txt +240 -9
- package/llms.txt +43 -2
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -1,37 +1,27 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🔔 agentrem
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/agentrem)
|
|
4
|
+
[](https://github.com/fraction12/agentrem)
|
|
4
5
|
[](https://github.com/fraction12/agentrem/actions/workflows/ci.yml)
|
|
5
|
-
[](https://github.com/fraction12/agentrem)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://nodejs.org)
|
|
8
8
|
[](https://modelcontextprotocol.io)
|
|
9
9
|
|
|
10
|
-
Structured reminders
|
|
10
|
+
Structured reminders for AI agents. Persistent, searchable, works across sessions.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## Install
|
|
12
|
+
## Instant Start
|
|
15
13
|
|
|
16
14
|
```bash
|
|
17
|
-
|
|
18
|
-
agentrem
|
|
15
|
+
npx agentrem add "Deploy to prod" --due tomorrow --priority 2
|
|
16
|
+
npx agentrem check
|
|
17
|
+
npx agentrem list
|
|
19
18
|
```
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
---
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
## For AI Agents
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
**1. Install globally:**
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm install -g agentrem
|
|
31
|
-
agentrem init
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
**2. Add to your `CLAUDE.md`:**
|
|
24
|
+
Copy this into your `CLAUDE.md` / `AGENTS.md` (or run `agentrem setup` to generate it):
|
|
35
25
|
|
|
36
26
|
```markdown
|
|
37
27
|
## Reminders
|
|
@@ -53,19 +43,11 @@ agentrem add "<content>" --due "<when>" --priority <1-5> --tags "<tags>"
|
|
|
53
43
|
- `agentrem --help` — full reference
|
|
54
44
|
```
|
|
55
45
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
agentrem add "Deploy to production" --due "tomorrow 9am" --priority 2
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Next session, `agentrem check` surfaces it automatically.
|
|
46
|
+
---
|
|
63
47
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
For Claude Desktop (the chat app), use the MCP server:
|
|
48
|
+
## MCP Server
|
|
67
49
|
|
|
68
|
-
|
|
50
|
+
For Claude Desktop and any MCP client — add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
69
51
|
|
|
70
52
|
```json
|
|
71
53
|
{
|
|
@@ -78,7 +60,7 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
78
60
|
}
|
|
79
61
|
```
|
|
80
62
|
|
|
81
|
-
|
|
63
|
+
No global install? Use `npx`:
|
|
82
64
|
|
|
83
65
|
```json
|
|
84
66
|
{
|
|
@@ -91,148 +73,141 @@ Or without global install:
|
|
|
91
73
|
}
|
|
92
74
|
```
|
|
93
75
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
76
|
+
Run `agentrem setup --mcp` to print this config. MCP tools: `add_reminder` · `check_reminders` · `list_reminders` · `search_reminders` · `complete_reminder` · `snooze_reminder` · `edit_reminder` · `delete_reminder` · `get_stats` · `undo_change` · `export_reminders` · `import_reminders`
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## All Commands
|
|
81
|
+
|
|
82
|
+
| Command | Key Flags | Example |
|
|
83
|
+
|---------|-----------|---------|
|
|
84
|
+
| `add <content>` | `--due` `--priority` `--tags` `--trigger` `--recur` `--agent` `--dry-run` | `agentrem add "PR review" --due "+4h" --priority 2` |
|
|
85
|
+
| `check` | `--type` `--text` `--budget` `--format` `--json` `--escalate` `--agent` | `agentrem check --type time,session --budget 800 --json` |
|
|
86
|
+
| `list` | `--status` `--priority` `--tag` `--due` `--limit` `--json` `--all` `--agent` | `agentrem list --priority 1,2 --json` |
|
|
87
|
+
| `search <query>` | `--status` `--limit` `--json` | `agentrem search "deploy staging" --json` |
|
|
88
|
+
| `complete <id>` | `--notes` | `agentrem complete abc12345` |
|
|
89
|
+
| `snooze <id>` | `--until` `--for` | `agentrem snooze abc12345 --for 2h` |
|
|
90
|
+
| `edit <id>` | `--content` `--due` `--priority` `--tags` `--add-tags` `--remove-tags` | `agentrem edit abc12345 --priority 1` |
|
|
91
|
+
| `delete [id]` | `--permanent` `--status` `--older-than` | `agentrem delete abc12345 --permanent` |
|
|
92
|
+
| `stats` | `--json` | `agentrem stats --json` |
|
|
93
|
+
| `history [id]` | `--limit` `--json` | `agentrem history --limit 20 --json` |
|
|
94
|
+
| `undo <history_id>` | — | `agentrem undo 42` |
|
|
95
|
+
| `gc` | `--older-than` `--dry-run` | `agentrem gc --older-than 30` |
|
|
96
|
+
| `export` | `--out` `--status` | `agentrem export --out backup.json` |
|
|
97
|
+
| `import <file>` | `--merge` `--replace` `--dry-run` | `agentrem import backup.json --merge` |
|
|
98
|
+
| `watch` | `--interval` `--once` `--verbose` `--install` `--uninstall` `--status` `--agent` | `agentrem watch --install` |
|
|
99
|
+
| `setup` | `--mcp` | `agentrem setup` / `agentrem setup --mcp` |
|
|
100
|
+
| `doctor` | `--json` | `agentrem doctor` |
|
|
101
|
+
| `init` | `--force` | `agentrem init` |
|
|
102
|
+
| `quickstart` | — | `agentrem quickstart` |
|
|
103
|
+
| `schema` | — | `agentrem schema` |
|
|
104
|
+
|
|
105
|
+
**`--json` is available on `check`, `list`, `search`, `stats`, `history`, `doctor` — use it for structured output in your agent.**
|
|
106
|
+
|
|
107
|
+
### Trigger Types
|
|
99
108
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
| Type | Fires when... | Key flags |
|
|
110
|
+
|------|--------------|-----------|
|
|
111
|
+
| `time` | Due datetime is reached | `--due` |
|
|
112
|
+
| `keyword` | Message text matches | `--keywords`, `--match any\|all\|regex` |
|
|
113
|
+
| `condition` | Shell command output matches | `--check`, `--expect` |
|
|
114
|
+
| `session` | Every session start check | — |
|
|
115
|
+
| `heartbeat` | Every heartbeat check | — |
|
|
116
|
+
| `manual` | Explicit `check` only | — |
|
|
103
117
|
|
|
104
|
-
|
|
105
|
-
# Session start hook
|
|
106
|
-
agentrem check --type time,session --budget 800
|
|
118
|
+
### Priority Levels
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
| Level | Label | Behavior |
|
|
121
|
+
|-------|-------|----------|
|
|
122
|
+
| 1 | 🔴 Critical | Always surfaced |
|
|
123
|
+
| 2 | 🟡 High | Surfaced within 60% budget |
|
|
124
|
+
| 3 | 🔵 Normal | Surfaced within 85% budget |
|
|
125
|
+
| 4 | ⚪ Low | Counted but not surfaced |
|
|
126
|
+
| 5 | 💤 Someday | Skipped entirely |
|
|
110
127
|
|
|
111
|
-
|
|
112
|
-
agentrem check --escalate && agentrem gc --days 30
|
|
113
|
-
```
|
|
128
|
+
---
|
|
114
129
|
|
|
115
|
-
|
|
130
|
+
## Natural Language Dates
|
|
116
131
|
|
|
117
|
-
|
|
132
|
+
`--due`, `--until`, and `--decay` all accept natural language:
|
|
118
133
|
|
|
119
134
|
```bash
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
135
|
+
--due "now" # Immediately
|
|
136
|
+
--due "today" # Today at 23:59
|
|
137
|
+
--due "tomorrow" # Tomorrow at 09:00
|
|
138
|
+
--due "in 5 minutes"
|
|
139
|
+
--due "in 2 hours"
|
|
140
|
+
--due "in 3 days"
|
|
141
|
+
--due "in 1 week"
|
|
142
|
+
--due "+5m" # Short relative
|
|
143
|
+
--due "+2h"
|
|
144
|
+
--due "+3d"
|
|
145
|
+
--due "+1w"
|
|
146
|
+
--due "2026-04-01T09:00:00" # ISO datetime
|
|
147
|
+
--due "2026-04-01" # ISO date
|
|
123
148
|
```
|
|
124
149
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
# Time-triggered reminder
|
|
129
|
-
agentrem add "Deploy v2.1 to staging" --due "+2h" --priority 2 --tags "deploy,staging"
|
|
130
|
-
|
|
131
|
-
# Keyword-triggered (fires when text matches)
|
|
132
|
-
agentrem add "Review security checklist" --trigger keyword --keywords "deploy,release" --match any
|
|
133
|
-
|
|
134
|
-
# Session reminder (fires every session start)
|
|
135
|
-
agentrem add "Check CI pipeline status" --trigger session
|
|
150
|
+
---
|
|
136
151
|
|
|
137
|
-
|
|
138
|
-
agentrem add "Weekly sync prep" --due "monday 9am" --recur 1w
|
|
152
|
+
## Background Watcher
|
|
139
153
|
|
|
140
|
-
|
|
141
|
-
agentrem check
|
|
154
|
+
`agentrem watch` polls for due reminders and fires native OS notifications.
|
|
142
155
|
|
|
143
|
-
|
|
144
|
-
agentrem
|
|
145
|
-
|
|
146
|
-
#
|
|
147
|
-
agentrem
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
156
|
+
```bash
|
|
157
|
+
agentrem watch # Poll every 30s (foreground)
|
|
158
|
+
agentrem watch --interval 60 # Custom interval
|
|
159
|
+
agentrem watch --once # Single check and exit
|
|
160
|
+
agentrem watch --agent jarvis # Watch for a specific agent
|
|
161
|
+
agentrem watch --verbose # Show poll log
|
|
162
|
+
|
|
163
|
+
# Install as OS service (auto-start on boot)
|
|
164
|
+
agentrem watch --install
|
|
165
|
+
agentrem watch --install --interval 60
|
|
166
|
+
agentrem watch --status
|
|
167
|
+
agentrem watch --uninstall
|
|
151
168
|
```
|
|
152
169
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
| Command | Description |
|
|
156
|
-
|---------|-------------|
|
|
157
|
-
| `init` | Initialize database (`--force` to recreate with backup) |
|
|
158
|
-
| `add <content>` | Create a reminder |
|
|
159
|
-
| `check` | Check for triggered reminders |
|
|
160
|
-
| `list` | List reminders with filters |
|
|
161
|
-
| `search <query>` | Full-text search across all fields |
|
|
162
|
-
| `complete <id>` | Mark done (auto-creates next if recurring) |
|
|
163
|
-
| `snooze <id>` | Snooze (`--until` or `--for`) |
|
|
164
|
-
| `edit <id>` | Edit reminder fields |
|
|
165
|
-
| `delete [id]` | Soft-delete (`--permanent` for hard delete) |
|
|
166
|
-
| `stats` | Show statistics |
|
|
167
|
-
| `gc` | Garbage collect old reminders |
|
|
168
|
-
| `history [id]` | View audit trail |
|
|
169
|
-
| `undo <history_id>` | Revert a change |
|
|
170
|
-
| `export` | Export to JSON |
|
|
171
|
-
| `import <file>` | Import from JSON |
|
|
172
|
-
| `schema` | Show database schema |
|
|
173
|
-
|
|
174
|
-
## Trigger Types
|
|
170
|
+
**Service files:** macOS → `~/Library/LaunchAgents/com.agentrem.watch.plist` · Linux → `~/.config/systemd/user/agentrem-watch.service` · Logs → `~/.agentrem/logs/watch.log`
|
|
175
171
|
|
|
176
|
-
|
|
177
|
-
|------|--------------|-----------|
|
|
178
|
-
| `time` | Due datetime is reached | `--due` |
|
|
179
|
-
| `keyword` | Text matches keywords | `--keywords`, `--match` |
|
|
180
|
-
| `condition` | Shell command matches expected output | `--check`, `--expect` |
|
|
181
|
-
| `session` | Every session check | — |
|
|
182
|
-
| `heartbeat` | Every heartbeat check | — |
|
|
183
|
-
| `manual` | Only via explicit check | — |
|
|
172
|
+
---
|
|
184
173
|
|
|
185
|
-
##
|
|
174
|
+
## Native Notifications 🔔
|
|
186
175
|
|
|
187
|
-
|
|
188
|
-
|-------|-------|----------|
|
|
189
|
-
| 1 | 🔴 Critical | Always surfaced |
|
|
190
|
-
| 2 | 🟡 High | Surfaced within 60% budget |
|
|
191
|
-
| 3 | 🔵 Normal | Surfaced within 85% budget |
|
|
192
|
-
| 4 | ⚪ Low | Counted but not surfaced |
|
|
193
|
-
| 5 | 💤 Someday | Skipped entirely |
|
|
176
|
+
On macOS, agentrem ships a bundled Swift app (`Agentrem.app`) so notifications appear with a bell icon — not a terminal icon.
|
|
194
177
|
|
|
195
|
-
|
|
178
|
+
| Priority | Sound |
|
|
179
|
+
|----------|-------|
|
|
180
|
+
| P1 🔴 Critical | Hero |
|
|
181
|
+
| P2 🟡 High | Ping |
|
|
182
|
+
| P3 🔵 Normal | Pop |
|
|
196
183
|
|
|
197
|
-
|
|
198
|
-
- **Dependencies** — `--depends-on <id>` blocks until dependency is completed
|
|
199
|
-
- **Decay** — `--decay <datetime>` auto-expires after a date
|
|
200
|
-
- **Max fires** — `--max-fires <n>` auto-completes after N triggers
|
|
201
|
-
- **Escalation** — `check --escalate` promotes overdue (P3→P2 after 48h, P2→P1 after 24h)
|
|
202
|
-
- **Token budget** — `check --budget <n>` limits output to fit context windows
|
|
203
|
-
- **Full-text search** — FTS5 across content, context, tags, notes
|
|
204
|
-
- **Undo** — revert any change via audit history
|
|
205
|
-
- **Multi-agent** — `--agent <name>` isolates reminders per agent
|
|
206
|
-
- **Export/Import** — JSON backup with merge and replace modes
|
|
184
|
+
**Backend fallback order:** `Agentrem.app` → `terminal-notifier` → `osascript` → `console`
|
|
207
185
|
|
|
208
|
-
|
|
186
|
+
Notifications include a **Complete** button and cheeky overdue messages. To rebuild the Swift app: `npm run build:notify`
|
|
209
187
|
|
|
210
|
-
|
|
188
|
+
---
|
|
211
189
|
|
|
212
|
-
|
|
213
|
-
`add_reminder` · `check_reminders` · `list_reminders` · `search_reminders` · `complete_reminder` · `snooze_reminder` · `edit_reminder` · `delete_reminder` · `get_stats` · `get_history` · `undo_change` · `garbage_collect` · `export_reminders` · `import_reminders`
|
|
190
|
+
## Why agentrem?
|
|
214
191
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
- `agentrem://schema` — database schema
|
|
192
|
+
```
|
|
193
|
+
# vs flat files / memory.md
|
|
194
|
+
agentrem check --json # structured output your agent can parse; memory.md can't do that
|
|
195
|
+
```
|
|
220
196
|
|
|
221
|
-
|
|
222
|
-
- `
|
|
223
|
-
-
|
|
224
|
-
-
|
|
197
|
+
- **Persistent across sessions** — SQLite-backed, survives restarts, not just in-context notes
|
|
198
|
+
- **Priority-aware + token budgets** — `check --budget 800` fits within any context window without overflow
|
|
199
|
+
- **Triggerable** — time, keyword, condition, session, heartbeat triggers; not just static lists
|
|
200
|
+
- **Agent-native** — `--json` everywhere, `--agent` namespacing, MCP server for chat clients
|
|
225
201
|
|
|
226
|
-
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Install
|
|
227
205
|
|
|
228
206
|
```bash
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
npm install
|
|
232
|
-
npm run build
|
|
233
|
-
npm test # 292 tests
|
|
207
|
+
npm install -g agentrem
|
|
208
|
+
agentrem init
|
|
234
209
|
```
|
|
235
210
|
|
|
236
|
-
|
|
211
|
+
Then run `agentrem setup` to get your `CLAUDE.md` snippet, or `agentrem setup --mcp` for Claude Desktop.
|
|
237
212
|
|
|
238
|
-
MIT
|
|
213
|
+
MIT License
|
|
@@ -14,5 +14,16 @@
|
|
|
14
14
|
<string>APPL</string>
|
|
15
15
|
<key>LSUIElement</key>
|
|
16
16
|
<true/>
|
|
17
|
+
<key>CFBundleURLTypes</key>
|
|
18
|
+
<array>
|
|
19
|
+
<dict>
|
|
20
|
+
<key>CFBundleURLSchemes</key>
|
|
21
|
+
<array>
|
|
22
|
+
<string>agentrem</string>
|
|
23
|
+
</array>
|
|
24
|
+
<key>CFBundleURLName</key>
|
|
25
|
+
<string>com.agentrem.notifier</string>
|
|
26
|
+
</dict>
|
|
27
|
+
</array>
|
|
17
28
|
</dict>
|
|
18
29
|
</plist>
|
|
Binary file
|
|
@@ -8,6 +8,7 @@ struct NotifyPayload: Decodable {
|
|
|
8
8
|
let subtitle: String?
|
|
9
9
|
let message: String
|
|
10
10
|
let sound: String?
|
|
11
|
+
let reminderId: String?
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
// ── Read JSON file from argv[1] or process args ──────────────────────────────
|
|
@@ -23,49 +24,118 @@ for i in 1..<args.count {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
// Parse payload if a JSON path was provided (nil when relaunched for action handling)
|
|
28
|
+
var parsedPayload: NotifyPayload? = nil
|
|
29
|
+
if let path = jsonPath {
|
|
30
|
+
if let fileData = try? Data(contentsOf: URL(fileURLWithPath: path)),
|
|
31
|
+
let decoded = try? JSONDecoder().decode(NotifyPayload.self, from: fileData) {
|
|
32
|
+
parsedPayload = decoded
|
|
33
|
+
} else {
|
|
34
|
+
fputs("agentrem-notify: failed to read or decode \(path)\n", stderr)
|
|
35
|
+
exit(1)
|
|
36
|
+
}
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
// ── Set up as proper NSApplication (required for UNUserNotificationCenter) ───
|
|
38
40
|
|
|
39
41
|
class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate {
|
|
40
|
-
let payload: NotifyPayload
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
let payload: NotifyPayload?
|
|
43
|
+
var timeoutWorkItem: DispatchWorkItem?
|
|
44
|
+
|
|
45
|
+
init(payload: NotifyPayload?) {
|
|
43
46
|
self.payload = payload
|
|
44
47
|
super.init()
|
|
45
48
|
}
|
|
46
|
-
|
|
49
|
+
|
|
50
|
+
// ── Shared logging ────────────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
func log(_ msg: String) {
|
|
53
|
+
let logPath = NSHomeDirectory() + "/.agentrem/logs/notify-actions.log"
|
|
54
|
+
let ts = ISO8601DateFormatter().string(from: Date())
|
|
55
|
+
let line = "[\(ts)] \(msg)\n"
|
|
56
|
+
if let fh = FileHandle(forWritingAtPath: logPath) {
|
|
57
|
+
fh.seekToEndOfFile()
|
|
58
|
+
fh.write(line.data(using: .utf8)!)
|
|
59
|
+
fh.closeFile()
|
|
60
|
+
} else {
|
|
61
|
+
// Create parent dirs if needed
|
|
62
|
+
try? FileManager.default.createDirectory(
|
|
63
|
+
atPath: NSHomeDirectory() + "/.agentrem/logs",
|
|
64
|
+
withIntermediateDirectories: true)
|
|
65
|
+
FileManager.default.createFile(atPath: logPath, contents: line.data(using: .utf8))
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── Run `agentrem complete <reminderId>` ──────────────────────────────────
|
|
70
|
+
|
|
71
|
+
func runComplete(reminderId: String) {
|
|
72
|
+
log("Running: agentrem complete \(reminderId)")
|
|
73
|
+
let proc = Process()
|
|
74
|
+
proc.executableURL = URL(fileURLWithPath: "/opt/homebrew/bin/node")
|
|
75
|
+
proc.arguments = ["/opt/homebrew/lib/node_modules/agentrem/dist/index.js", "complete", reminderId]
|
|
76
|
+
proc.environment = ["HOME": NSHomeDirectory(), "PATH": "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"]
|
|
77
|
+
do {
|
|
78
|
+
try proc.run()
|
|
79
|
+
proc.waitUntilExit()
|
|
80
|
+
log("Complete exited with code \(proc.terminationStatus)")
|
|
81
|
+
} catch {
|
|
82
|
+
log("ERROR running complete: \(error.localizedDescription)")
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
47
86
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
|
48
87
|
let center = UNUserNotificationCenter.current()
|
|
49
88
|
center.delegate = self
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
89
|
+
|
|
90
|
+
// Register the "Complete ✅" action category so macOS shows the button.
|
|
91
|
+
// .foreground ensures the app is brought to foreground on tap, making
|
|
92
|
+
// the didReceive callback fire reliably even after relaunch.
|
|
93
|
+
let completeAction = UNNotificationAction(
|
|
94
|
+
identifier: "COMPLETE_REMINDER",
|
|
95
|
+
title: "Complete ✅",
|
|
96
|
+
options: []
|
|
97
|
+
)
|
|
98
|
+
let category = UNNotificationCategory(
|
|
99
|
+
identifier: "AGENTREM_REMINDER",
|
|
100
|
+
actions: [completeAction],
|
|
101
|
+
intentIdentifiers: [],
|
|
102
|
+
options: []
|
|
103
|
+
)
|
|
104
|
+
center.setNotificationCategories([category])
|
|
105
|
+
|
|
106
|
+
if payload != nil {
|
|
107
|
+
// Normal launch: request permission then fire the notification
|
|
108
|
+
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
|
|
109
|
+
if let error = error {
|
|
110
|
+
fputs("agentrem-notify: auth error: \(error.localizedDescription)\n", stderr)
|
|
111
|
+
NSApp.terminate(nil)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
guard granted else {
|
|
115
|
+
fputs("agentrem-notify: notification permission not granted\n", stderr)
|
|
116
|
+
NSApp.terminate(nil)
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
self.postNotification()
|
|
62
120
|
}
|
|
63
|
-
|
|
64
|
-
self.postNotification()
|
|
65
121
|
}
|
|
122
|
+
// else: relaunched to handle an action or URL — wait for the delegate callback
|
|
123
|
+
|
|
124
|
+
// Terminate after 10 s whether or not we handle an action
|
|
125
|
+
scheduleTimeout(seconds: 10.0)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
func scheduleTimeout(seconds: Double) {
|
|
129
|
+
let work = DispatchWorkItem {
|
|
130
|
+
NSApp.terminate(nil)
|
|
131
|
+
}
|
|
132
|
+
timeoutWorkItem = work
|
|
133
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + seconds, execute: work)
|
|
66
134
|
}
|
|
67
|
-
|
|
135
|
+
|
|
68
136
|
func postNotification() {
|
|
137
|
+
guard let payload = payload else { return }
|
|
138
|
+
|
|
69
139
|
let content = UNMutableNotificationContent()
|
|
70
140
|
content.title = payload.title
|
|
71
141
|
content.body = payload.message
|
|
@@ -75,24 +145,78 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
|
|
75
145
|
} else {
|
|
76
146
|
content.sound = .default
|
|
77
147
|
}
|
|
78
|
-
|
|
148
|
+
|
|
149
|
+
// Attach category so the "Complete ✅" button appears
|
|
150
|
+
content.categoryIdentifier = "AGENTREM_REMINDER"
|
|
151
|
+
|
|
152
|
+
// Pass reminderId (and URL scheme backup) so we can call `agentrem complete`
|
|
153
|
+
if let reminderId = payload.reminderId {
|
|
154
|
+
content.userInfo = [
|
|
155
|
+
"reminderId": reminderId,
|
|
156
|
+
"url": "agentrem://complete/\(reminderId)"
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
|
|
79
160
|
let request = UNNotificationRequest(
|
|
80
161
|
identifier: UUID().uuidString,
|
|
81
162
|
content: content,
|
|
82
163
|
trigger: nil
|
|
83
164
|
)
|
|
84
|
-
|
|
165
|
+
|
|
85
166
|
UNUserNotificationCenter.current().add(request) { error in
|
|
86
167
|
if let error = error {
|
|
87
168
|
fputs("agentrem-notify: post error: \(error.localizedDescription)\n", stderr)
|
|
88
|
-
}
|
|
89
|
-
// Give the notification a moment to display
|
|
90
|
-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
|
91
169
|
NSApp.terminate(nil)
|
|
92
170
|
}
|
|
171
|
+
// Stay alive for 10 s to handle an immediate action tap;
|
|
172
|
+
// the timeout scheduled in applicationDidFinishLaunching covers this.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ── URL scheme handler (agentrem://complete/<reminderId>) ─────────────────
|
|
177
|
+
|
|
178
|
+
func application(_ application: NSApplication, open urls: [URL]) {
|
|
179
|
+
for url in urls {
|
|
180
|
+
log("application:open URL=\(url.absoluteString)")
|
|
181
|
+
guard url.scheme == "agentrem",
|
|
182
|
+
url.host == "complete" else {
|
|
183
|
+
log("Unrecognised URL, ignoring: \(url.absoluteString)")
|
|
184
|
+
continue
|
|
185
|
+
}
|
|
186
|
+
// Path is "/<reminderId>" — strip leading slash
|
|
187
|
+
let reminderId = url.path.hasPrefix("/")
|
|
188
|
+
? String(url.path.dropFirst())
|
|
189
|
+
: url.path
|
|
190
|
+
guard !reminderId.isEmpty else {
|
|
191
|
+
log("URL missing reminderId: \(url.absoluteString)")
|
|
192
|
+
continue
|
|
193
|
+
}
|
|
194
|
+
runComplete(reminderId: reminderId)
|
|
195
|
+
}
|
|
196
|
+
timeoutWorkItem?.cancel()
|
|
197
|
+
NSApp.terminate(nil)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ── Action handler ────────────────────────────────────────────────────────
|
|
201
|
+
|
|
202
|
+
func userNotificationCenter(_ center: UNUserNotificationCenter,
|
|
203
|
+
didReceive response: UNNotificationResponse,
|
|
204
|
+
withCompletionHandler completionHandler: @escaping () -> Void) {
|
|
205
|
+
log("didReceive action=\(response.actionIdentifier) userInfo=\(response.notification.request.content.userInfo)")
|
|
206
|
+
|
|
207
|
+
if response.actionIdentifier == "COMPLETE_REMINDER" {
|
|
208
|
+
if let reminderId = response.notification.request.content.userInfo["reminderId"] as? String,
|
|
209
|
+
!reminderId.isEmpty {
|
|
210
|
+
runComplete(reminderId: reminderId)
|
|
211
|
+
} else {
|
|
212
|
+
log("No reminderId in userInfo")
|
|
213
|
+
}
|
|
93
214
|
}
|
|
215
|
+
completionHandler()
|
|
216
|
+
timeoutWorkItem?.cancel()
|
|
217
|
+
NSApp.terminate(nil)
|
|
94
218
|
}
|
|
95
|
-
|
|
219
|
+
|
|
96
220
|
// Show notification even when app is in foreground
|
|
97
221
|
func userNotificationCenter(_ center: UNUserNotificationCenter,
|
|
98
222
|
willPresent notification: UNNotification,
|
|
@@ -103,6 +227,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
|
|
103
227
|
|
|
104
228
|
let app = NSApplication.shared
|
|
105
229
|
app.setActivationPolicy(.accessory) // No dock icon
|
|
106
|
-
let delegate = AppDelegate(payload:
|
|
230
|
+
let delegate = AppDelegate(payload: parsedPayload)
|
|
107
231
|
app.delegate = delegate
|
|
108
232
|
app.run()
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { type StatsResult } from './core.js';
|
|
2
|
+
import type { Reminder } from './types.js';
|
|
3
|
+
export type { Reminder } from './types.js';
|
|
4
|
+
export type { StatsResult } from './core.js';
|
|
5
|
+
export interface CheckResult {
|
|
6
|
+
/** Reminders that fired and fit within the token budget */
|
|
7
|
+
included: Reminder[];
|
|
8
|
+
/** Count of reminders not returned per priority level due to budget */
|
|
9
|
+
overflowCounts: Record<number, number>;
|
|
10
|
+
/** Total number of reminders that triggered (before budget trim) */
|
|
11
|
+
totalTriggered: number;
|
|
12
|
+
}
|
|
13
|
+
/** Reset the internal DB singleton (useful for testing with custom DB paths). */
|
|
14
|
+
export declare function _resetDb(): void;
|
|
15
|
+
export interface AddOptions {
|
|
16
|
+
due?: string;
|
|
17
|
+
priority?: number;
|
|
18
|
+
tags?: string;
|
|
19
|
+
agent?: string;
|
|
20
|
+
context?: string;
|
|
21
|
+
trigger?: string;
|
|
22
|
+
category?: string;
|
|
23
|
+
keywords?: string;
|
|
24
|
+
recur?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Add a new reminder.
|
|
28
|
+
* @example
|
|
29
|
+
* const rem = await add('Review PR', { due: 'tomorrow', priority: 2 });
|
|
30
|
+
*/
|
|
31
|
+
export declare function add(content: string, opts?: AddOptions): Promise<Reminder>;
|
|
32
|
+
export interface CheckOptions {
|
|
33
|
+
type?: string;
|
|
34
|
+
budget?: number;
|
|
35
|
+
agent?: string;
|
|
36
|
+
format?: 'text' | 'json';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check for triggered reminders. Returns all reminders that are currently
|
|
40
|
+
* due/active within the given token budget.
|
|
41
|
+
* @example
|
|
42
|
+
* const { included } = await check({ budget: 500 });
|
|
43
|
+
*/
|
|
44
|
+
export declare function check(opts?: CheckOptions): Promise<CheckResult>;
|
|
45
|
+
export interface ListOptions {
|
|
46
|
+
filter?: string;
|
|
47
|
+
agent?: string;
|
|
48
|
+
limit?: number;
|
|
49
|
+
status?: string;
|
|
50
|
+
priority?: string;
|
|
51
|
+
tag?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* List reminders.
|
|
55
|
+
* @example
|
|
56
|
+
* const reminders = await list({ limit: 10 });
|
|
57
|
+
*/
|
|
58
|
+
export declare function list(opts?: ListOptions): Promise<Reminder[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Mark a reminder as completed.
|
|
61
|
+
* @example
|
|
62
|
+
* const done = await complete('abc123');
|
|
63
|
+
*/
|
|
64
|
+
export declare function complete(id: string, notes?: string): Promise<Reminder>;
|
|
65
|
+
export interface SnoozeOptions {
|
|
66
|
+
for: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Snooze a reminder for a duration.
|
|
70
|
+
* @example
|
|
71
|
+
* const snoozed = await snooze('abc123', { for: '2h' });
|
|
72
|
+
*/
|
|
73
|
+
export declare function snooze(id: string, opts: SnoozeOptions): Promise<Reminder>;
|
|
74
|
+
export interface SearchOptions {
|
|
75
|
+
limit?: number;
|
|
76
|
+
agent?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Full-text search reminders.
|
|
80
|
+
* @example
|
|
81
|
+
* const results = await search('PR review');
|
|
82
|
+
*/
|
|
83
|
+
export declare function search(query: string, opts?: SearchOptions): Promise<Reminder[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Get reminder statistics.
|
|
86
|
+
* @example
|
|
87
|
+
* const s = await stats();
|
|
88
|
+
* console.log(s.totalActive);
|
|
89
|
+
*/
|
|
90
|
+
export declare function stats(opts?: {
|
|
91
|
+
agent?: string;
|
|
92
|
+
}): Promise<StatsResult>;
|
|
93
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAMA,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAI7C,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,uEAAuE;IACvE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;CACxB;AAeD,iFAAiF;AACjF,wBAAgB,QAAQ,IAAI,IAAI,CAK/B;AAID,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAc/E;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAMrE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAQlE;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAG5E;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAE/E;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAKrF;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAG3E"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// ── Programmatic JavaScript API ───────────────────────────────────────────
|
|
2
|
+
// Clean async wrappers for use by agents and scripts.
|
|
3
|
+
// import { add, check, list, complete, search } from 'agentrem'
|
|
4
|
+
import { initDb, getDb } from './db.js';
|
|
5
|
+
import { coreAdd, coreCheck, coreList, coreSearch, coreComplete, coreSnooze, coreStats, } from './core.js';
|
|
6
|
+
// ── Lazy DB singleton ──────────────────────────────────────────────────────
|
|
7
|
+
let _db = null;
|
|
8
|
+
function db() {
|
|
9
|
+
if (!_db) {
|
|
10
|
+
// Auto-init on first call so `import { add } from 'agentrem'` just works
|
|
11
|
+
initDb(false);
|
|
12
|
+
_db = getDb();
|
|
13
|
+
}
|
|
14
|
+
return _db;
|
|
15
|
+
}
|
|
16
|
+
/** Reset the internal DB singleton (useful for testing with custom DB paths). */
|
|
17
|
+
export function _resetDb() {
|
|
18
|
+
if (_db) {
|
|
19
|
+
try {
|
|
20
|
+
_db.close();
|
|
21
|
+
}
|
|
22
|
+
catch { /* ignore */ }
|
|
23
|
+
_db = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Add a new reminder.
|
|
28
|
+
* @example
|
|
29
|
+
* const rem = await add('Review PR', { due: 'tomorrow', priority: 2 });
|
|
30
|
+
*/
|
|
31
|
+
export async function add(content, opts) {
|
|
32
|
+
const result = coreAdd(db(), {
|
|
33
|
+
content,
|
|
34
|
+
due: opts?.due,
|
|
35
|
+
priority: opts?.priority,
|
|
36
|
+
tags: opts?.tags,
|
|
37
|
+
agent: opts?.agent,
|
|
38
|
+
context: opts?.context,
|
|
39
|
+
trigger: opts?.trigger,
|
|
40
|
+
category: opts?.category,
|
|
41
|
+
keywords: opts?.keywords,
|
|
42
|
+
recur: opts?.recur,
|
|
43
|
+
});
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check for triggered reminders. Returns all reminders that are currently
|
|
48
|
+
* due/active within the given token budget.
|
|
49
|
+
* @example
|
|
50
|
+
* const { included } = await check({ budget: 500 });
|
|
51
|
+
*/
|
|
52
|
+
export async function check(opts) {
|
|
53
|
+
return coreCheck(db(), {
|
|
54
|
+
type: opts?.type,
|
|
55
|
+
budget: opts?.budget,
|
|
56
|
+
agent: opts?.agent,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* List reminders.
|
|
61
|
+
* @example
|
|
62
|
+
* const reminders = await list({ limit: 10 });
|
|
63
|
+
*/
|
|
64
|
+
export async function list(opts) {
|
|
65
|
+
return coreList(db(), {
|
|
66
|
+
agent: opts?.agent,
|
|
67
|
+
limit: opts?.limit,
|
|
68
|
+
status: opts?.status,
|
|
69
|
+
priority: opts?.priority,
|
|
70
|
+
tag: opts?.tag ?? opts?.filter,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Mark a reminder as completed.
|
|
75
|
+
* @example
|
|
76
|
+
* const done = await complete('abc123');
|
|
77
|
+
*/
|
|
78
|
+
export async function complete(id, notes) {
|
|
79
|
+
const { completed } = coreComplete(db(), id, notes);
|
|
80
|
+
return completed;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Snooze a reminder for a duration.
|
|
84
|
+
* @example
|
|
85
|
+
* const snoozed = await snooze('abc123', { for: '2h' });
|
|
86
|
+
*/
|
|
87
|
+
export async function snooze(id, opts) {
|
|
88
|
+
return coreSnooze(db(), id, undefined, opts.for);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Full-text search reminders.
|
|
92
|
+
* @example
|
|
93
|
+
* const results = await search('PR review');
|
|
94
|
+
*/
|
|
95
|
+
export async function search(query, opts) {
|
|
96
|
+
return coreSearch(db(), {
|
|
97
|
+
query,
|
|
98
|
+
limit: opts?.limit,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get reminder statistics.
|
|
103
|
+
* @example
|
|
104
|
+
* const s = await stats();
|
|
105
|
+
* console.log(s.totalActive);
|
|
106
|
+
*/
|
|
107
|
+
export async function stats(opts) {
|
|
108
|
+
void opts; // agent filter not currently in coreStats; included for API compat
|
|
109
|
+
return coreStats(db());
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/notifier.d.ts
CHANGED
package/dist/notifier.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../src/notifier.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../src/notifier.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,mBAAmB,GAAG,WAAW,GAAG,SAAS,CAAC;AAM7F,8CAA8C;AAC9C,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wEAAwE;AACxE,wBAAgB,cAAc,IAAI,eAAe,CA2BhD;AAkBD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAapD;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAmB,GAAG,UAAU,CAgBnF;AA4BD,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAiBvD;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE3C"}
|
package/dist/notifier.js
CHANGED
|
@@ -86,7 +86,7 @@ export function buildNotifyOpts(rem, now = Date.now()) {
|
|
|
86
86
|
}
|
|
87
87
|
const message = truncate(rem.content, 80);
|
|
88
88
|
const sound = PRIORITY_SOUNDS[rem.priority]; // undefined for P4/P5
|
|
89
|
-
return { title, subtitle, message, sound, group: 'com.agentrem.watch' };
|
|
89
|
+
return { title, subtitle, message, sound, group: 'com.agentrem.watch', reminderId: rem.id };
|
|
90
90
|
}
|
|
91
91
|
// ── Path helpers ─────────────────────────────────────────────────────────────
|
|
92
92
|
/** Resolve the bundled .app bundle path. Returns undefined if it doesn't exist. */
|
|
@@ -148,6 +148,7 @@ function sendViaAgentremApp(opts) {
|
|
|
148
148
|
subtitle: opts.subtitle,
|
|
149
149
|
message: opts.message,
|
|
150
150
|
sound: opts.sound,
|
|
151
|
+
reminderId: opts.reminderId,
|
|
151
152
|
});
|
|
152
153
|
writeFileSync(tmpPath, payload, 'utf8');
|
|
153
154
|
try {
|
package/dist/notifier.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifier.js","sourceRoot":"","sources":["../src/notifier.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,2FAA2F;AAC3F,+DAA+D;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"notifier.js","sourceRoot":"","sources":["../src/notifier.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const SCHEMA_VERSION = 1;
|
|
2
|
-
export declare const VERSION = "1.
|
|
2
|
+
export declare const VERSION = "1.5.0";
|
|
3
3
|
export declare const PRIORITY_LABELS: Record<number, string>;
|
|
4
4
|
export declare const PRIORITY_COLORS: Record<number, string>;
|
|
5
5
|
export declare const VALID_TRIGGERS: Set<string>;
|
package/dist/types.js
CHANGED
package/llms-full.txt
CHANGED
|
@@ -28,7 +28,7 @@ Create a reminder.
|
|
|
28
28
|
|
|
29
29
|
| Flag | Description | Example |
|
|
30
30
|
|------|-------------|---------|
|
|
31
|
-
| `--due, -d <datetime>` | Due datetime (
|
|
31
|
+
| `--due, -d <datetime>` | Due datetime (natural language or ISO) | `--due "+2h"`, `--due "tomorrow"`, `--due "in 5 minutes"` |
|
|
32
32
|
| `--trigger, -t <type>` | Trigger type: time/keyword/condition/session/heartbeat/manual | `--trigger keyword` |
|
|
33
33
|
| `--priority, -p <n>` | Priority 1-5 (default: 3) | `--priority 1` |
|
|
34
34
|
| `--tags <tags>` | Comma-separated tags | `--tags "deploy,urgent"` |
|
|
@@ -50,6 +50,10 @@ Create a reminder.
|
|
|
50
50
|
# Time reminder
|
|
51
51
|
agentrem add "Deploy v2" --due "+2h" --priority 2 --tags "deploy"
|
|
52
52
|
|
|
53
|
+
# Natural language due date
|
|
54
|
+
agentrem add "Team standup" --due "tomorrow" --priority 3
|
|
55
|
+
agentrem add "Send report" --due "in 30 minutes"
|
|
56
|
+
|
|
53
57
|
# Keyword trigger
|
|
54
58
|
agentrem add "Review security" --trigger keyword --keywords "deploy,release" --match any
|
|
55
59
|
|
|
@@ -57,7 +61,7 @@ agentrem add "Review security" --trigger keyword --keywords "deploy,release" --m
|
|
|
57
61
|
agentrem add "Check CI" --trigger session
|
|
58
62
|
|
|
59
63
|
# Recurring weekly
|
|
60
|
-
agentrem add "Team sync prep" --due "
|
|
64
|
+
agentrem add "Team sync prep" --due "2026-02-24T09:00:00" --recur 1w
|
|
61
65
|
|
|
62
66
|
# With dependency
|
|
63
67
|
agentrem add "Deploy" --due "+4h" --depends-on abc12345
|
|
@@ -175,7 +179,7 @@ Snooze a reminder.
|
|
|
175
179
|
|
|
176
180
|
```bash
|
|
177
181
|
agentrem snooze abc12345 --for 2h
|
|
178
|
-
agentrem snooze abc12345 --until "tomorrow
|
|
182
|
+
agentrem snooze abc12345 --until "tomorrow"
|
|
179
183
|
```
|
|
180
184
|
|
|
181
185
|
### agentrem edit <id>
|
|
@@ -187,7 +191,7 @@ Edit reminder fields.
|
|
|
187
191
|
| `--content <text>` | New content |
|
|
188
192
|
| `--context <ctx>` | New context |
|
|
189
193
|
| `--priority, -p <n>` | New priority |
|
|
190
|
-
| `--due, -d <datetime>` | New due date |
|
|
194
|
+
| `--due, -d <datetime>` | New due date (natural language or ISO) |
|
|
191
195
|
| `--tags <tags>` | Replace all tags |
|
|
192
196
|
| `--add-tags <tags>` | Add tags |
|
|
193
197
|
| `--remove-tags <tags>` | Remove tags |
|
|
@@ -200,6 +204,7 @@ Edit reminder fields.
|
|
|
200
204
|
```bash
|
|
201
205
|
agentrem edit abc12345 --priority 1
|
|
202
206
|
agentrem edit abc12345 --due "+4h" --add-tags "urgent"
|
|
207
|
+
agentrem edit abc12345 --due "in 2 hours"
|
|
203
208
|
```
|
|
204
209
|
|
|
205
210
|
### agentrem delete [id]
|
|
@@ -307,17 +312,218 @@ agentrem setup # Print CLAUDE.md snippet
|
|
|
307
312
|
agentrem setup --mcp # Print Claude Desktop MCP config
|
|
308
313
|
```
|
|
309
314
|
|
|
310
|
-
### agentrem
|
|
315
|
+
### agentrem doctor
|
|
311
316
|
|
|
312
|
-
|
|
317
|
+
Self-diagnostic command. Checks that the database exists and is healthy, schema is valid, and warns about overdue reminders or large DB size.
|
|
318
|
+
|
|
319
|
+
| Flag | Description |
|
|
320
|
+
|------|-------------|
|
|
321
|
+
| `--json` | Output structured JSON |
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
agentrem doctor
|
|
325
|
+
agentrem doctor --json
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Output:
|
|
329
|
+
```
|
|
330
|
+
🩺 agentrem doctor
|
|
331
|
+
|
|
332
|
+
✅ Database exists: /Users/you/.agentrem/reminders.db
|
|
333
|
+
✅ Schema valid: Tables: reminders, history, reminders_fts
|
|
334
|
+
⚠️ Active reminders: 0 active reminders. Add one: agentrem add "Test" --due "+1h"
|
|
335
|
+
✅ Database size: 64 KB
|
|
336
|
+
|
|
337
|
+
🟡 Some issues found.
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
JSON output example:
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"healthy": false,
|
|
344
|
+
"checks": [
|
|
345
|
+
{ "check": "Database exists", "status": "ok", "detail": "/Users/you/.agentrem/reminders.db" },
|
|
346
|
+
{ "check": "Schema valid", "status": "ok", "detail": "Tables: reminders, history, reminders_fts" },
|
|
347
|
+
{ "check": "Active reminders", "status": "warn", "detail": "No active reminders. Add one: agentrem add \"Test\" --due \"+1h\"" },
|
|
348
|
+
{ "check": "Database size", "status": "ok", "detail": "64 KB" }
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### agentrem quickstart
|
|
354
|
+
|
|
355
|
+
Interactive first-run walkthrough. Initializes the database (if needed), creates a sample reminder, runs a check, and cleans up — confirming everything works.
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
agentrem quickstart
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Output:
|
|
362
|
+
```
|
|
363
|
+
📦 Step 1/4: Initializing database...
|
|
364
|
+
📝 Step 2/4: Creating a sample reminder...
|
|
365
|
+
🔔 Step 3/4: Checking triggered reminders...
|
|
366
|
+
✅ Step 4/4: Completing the test reminder...
|
|
367
|
+
|
|
368
|
+
🎉 Quickstart complete! agentrem is working.
|
|
369
|
+
|
|
370
|
+
Next steps:
|
|
371
|
+
agentrem add "My first real reminder" --due "+1h" --priority 2
|
|
372
|
+
agentrem check
|
|
373
|
+
agentrem setup # Get your CLAUDE.md snippet
|
|
374
|
+
agentrem doctor # Run diagnostics anytime
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### agentrem watch
|
|
378
|
+
|
|
379
|
+
Background daemon that polls for due reminders and fires native OS notifications. Runs until interrupted (SIGINT/SIGTERM).
|
|
380
|
+
|
|
381
|
+
| Flag | Description |
|
|
382
|
+
|------|-------------|
|
|
383
|
+
| `--interval <seconds>` | Poll interval in seconds (default: 30) |
|
|
384
|
+
| `--agent, -a <name>` | Agent name to check for (default: main) |
|
|
385
|
+
| `--once` | Run a single check and exit |
|
|
386
|
+
| `--verbose` | Show poll log output |
|
|
387
|
+
| `--install` | Install as OS background service (launchd on macOS, systemd on Linux) |
|
|
388
|
+
| `--uninstall` | Remove the background service |
|
|
389
|
+
| `--status` | Show service status |
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
# Run in foreground
|
|
393
|
+
agentrem watch # Poll every 30s (default)
|
|
394
|
+
agentrem watch --interval 60 # Poll every 60s
|
|
395
|
+
agentrem watch --agent jarvis # Check reminders for agent "jarvis"
|
|
396
|
+
agentrem watch --once # Single check then exit
|
|
397
|
+
agentrem watch --verbose # Verbose logging
|
|
398
|
+
|
|
399
|
+
# Service management (auto-start on boot)
|
|
400
|
+
agentrem watch --install # Install and start service
|
|
401
|
+
agentrem watch --install --interval 60 # Install with custom interval
|
|
402
|
+
agentrem watch --uninstall # Stop and remove service
|
|
403
|
+
agentrem watch --status # Show installed/running status
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### How polling works
|
|
407
|
+
|
|
408
|
+
- Runs `coreCheck` with types `time,heartbeat,session,condition` and `--escalate` on every tick
|
|
409
|
+
- Per-reminder **dedup cooldown**: once a reminder is notified, it won't fire again for 5 minutes
|
|
410
|
+
- Handles SIGINT/SIGTERM for clean shutdown
|
|
411
|
+
- First check runs immediately on start
|
|
412
|
+
|
|
413
|
+
#### Service management
|
|
414
|
+
|
|
415
|
+
**macOS (launchd):**
|
|
416
|
+
- Writes a LaunchAgent plist to `~/Library/LaunchAgents/com.agentrem.watch.plist`
|
|
417
|
+
- Logs to `~/.agentrem/logs/watch.log` and `watch.error.log`
|
|
418
|
+
- Service label: `com.agentrem.watch`
|
|
419
|
+
- `KeepAlive: true` — restarts automatically on crash
|
|
420
|
+
|
|
421
|
+
**Linux (systemd):**
|
|
422
|
+
- Writes a user unit to `~/.config/systemd/user/agentrem-watch.service`
|
|
423
|
+
- Enabled with `systemctl --user enable --now`
|
|
424
|
+
- Logs to `~/.agentrem/logs/watch.log` and `watch.error.log`
|
|
425
|
+
|
|
426
|
+
#### watch --status output
|
|
427
|
+
|
|
428
|
+
```
|
|
429
|
+
✅ Installed: true
|
|
430
|
+
🟢 Running: true
|
|
431
|
+
Platform: darwin
|
|
432
|
+
File: /Users/you/Library/LaunchAgents/com.agentrem.watch.plist
|
|
433
|
+
Detail: launchctl: ...
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
#### watch --once (single check)
|
|
437
|
+
|
|
438
|
+
Useful in scripts or cron jobs to check once and exit. Combine with `--verbose` to see what fired:
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
agentrem watch --once --verbose
|
|
442
|
+
# [agentrem watch] started — interval=30s agent=main
|
|
443
|
+
# [agentrem watch] 🔔 [8f103c9c] Deploy v2
|
|
444
|
+
# [agentrem watch] checked at 2026-02-22T09:00:00.000Z — 1 triggered, 1 notified
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Native Notifications
|
|
450
|
+
|
|
451
|
+
agentrem ships a custom Swift app (`Agentrem.app`) bundled in `assets/`. When present, it is preferred over all other backends.
|
|
452
|
+
|
|
453
|
+
### Notification Backends (priority order)
|
|
454
|
+
|
|
455
|
+
| Backend | When used | Notes |
|
|
456
|
+
|---------|-----------|-------|
|
|
457
|
+
| `agentrem-app` | `Agentrem.app` found in `assets/` | Preferred. Shows "agentrem" as app name with 🔔 bell icon |
|
|
458
|
+
| `terminal-notifier` | `terminal-notifier` on PATH | Fallback if app missing |
|
|
459
|
+
| `osascript` | macOS, no terminal-notifier | Native AppleScript notifications |
|
|
460
|
+
| `console` | Linux / no other option | Prints to stdout |
|
|
461
|
+
|
|
462
|
+
### Priority-Based Sounds
|
|
463
|
+
|
|
464
|
+
| Priority | Sound |
|
|
465
|
+
|----------|-------|
|
|
466
|
+
| P1 Critical | Hero |
|
|
467
|
+
| P2 High | Ping |
|
|
468
|
+
| P3 Normal | Pop |
|
|
469
|
+
| P4–P5 | (no sound) |
|
|
470
|
+
|
|
471
|
+
### Overdue Messages
|
|
472
|
+
|
|
473
|
+
The notification subtitle changes based on how overdue a reminder is:
|
|
474
|
+
|
|
475
|
+
| Overdue duration | Subtitle |
|
|
476
|
+
|-----------------|----------|
|
|
477
|
+
| < 2 min | "just now" |
|
|
478
|
+
| < 30 min | "X min ago" |
|
|
479
|
+
| < 1 hour | "about an hour, no biggie" |
|
|
480
|
+
| < 3 hours | "been a couple hours..." |
|
|
481
|
+
| < 6 hours | "this has been waiting a while" |
|
|
482
|
+
| < 24 hours | "so... you forgot about this one 😅" |
|
|
483
|
+
| < 48 hours | "it's been a whole day, dude" |
|
|
484
|
+
| 2+ days | "I've been here for N days. just saying." |
|
|
485
|
+
|
|
486
|
+
### Rebuilding Agentrem.app
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
npm run build:notify # Recompile Swift source in assets/notify-src/
|
|
490
|
+
```
|
|
313
491
|
|
|
314
492
|
---
|
|
315
493
|
|
|
316
494
|
## Date/Time Formats
|
|
317
495
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
496
|
+
All date inputs (`--due`, `--until`, `--decay`, etc.) accept:
|
|
497
|
+
|
|
498
|
+
### Natural language
|
|
499
|
+
```
|
|
500
|
+
now # Immediately
|
|
501
|
+
today # Today at 23:59
|
|
502
|
+
tomorrow # Tomorrow at 09:00
|
|
503
|
+
in 5 minutes
|
|
504
|
+
in 2 hours
|
|
505
|
+
in 3 days
|
|
506
|
+
in 1 week
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Relative shortcuts
|
|
510
|
+
```
|
|
511
|
+
+5m # 5 minutes from now
|
|
512
|
+
+2h # 2 hours from now
|
|
513
|
+
+3d # 3 days from now
|
|
514
|
+
+1w # 1 week from now
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### ISO 8601
|
|
518
|
+
```
|
|
519
|
+
2026-02-22T09:00:00 # Full datetime
|
|
520
|
+
2026-02-22T09:00 # Without seconds
|
|
521
|
+
2026-02-22 09:00:00 # Space separator
|
|
522
|
+
2026-02-22 09:00 # Space, no seconds
|
|
523
|
+
2026-02-22 # Date only (00:00:00)
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
---
|
|
321
527
|
|
|
322
528
|
## Environment Variables
|
|
323
529
|
|
|
@@ -326,6 +532,8 @@ Absolute: `2026-03-01`, `2026-03-01T09:00:00`
|
|
|
326
532
|
| `AGENTREM_DB` | Database file path | `~/.agentrem/reminders.db` |
|
|
327
533
|
| `AGENTREM_DIR` | Data directory | `~/.agentrem` |
|
|
328
534
|
|
|
535
|
+
---
|
|
536
|
+
|
|
329
537
|
## MCP Server
|
|
330
538
|
|
|
331
539
|
```bash
|
|
@@ -334,3 +542,26 @@ npx agentrem mcp # Without global install
|
|
|
334
542
|
```
|
|
335
543
|
|
|
336
544
|
14 tools, 4 resources, 3 prompts. See README.md for full MCP reference.
|
|
545
|
+
|
|
546
|
+
### Claude Desktop Config
|
|
547
|
+
|
|
548
|
+
```json
|
|
549
|
+
{
|
|
550
|
+
"mcpServers": {
|
|
551
|
+
"agentrem": {
|
|
552
|
+
"command": "agentrem-mcp",
|
|
553
|
+
"args": []
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## agentrem schema
|
|
562
|
+
|
|
563
|
+
Print the database schema (useful for debugging).
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
agentrem schema
|
|
567
|
+
```
|
package/llms.txt
CHANGED
|
@@ -14,7 +14,7 @@ npm install -g agentrem && agentrem init
|
|
|
14
14
|
agentrem check --type time,session --budget 800
|
|
15
15
|
|
|
16
16
|
# 3. When your human says "remind me" — save it
|
|
17
|
-
agentrem add "Deploy to prod" --due "
|
|
17
|
+
agentrem add "Deploy to prod" --due "+2h" --priority 2
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Add `agentrem setup` output to your CLAUDE.md for automatic integration.
|
|
@@ -30,6 +30,9 @@ agentrem complete <id> # Mark done (auto-creates next if recurring)
|
|
|
30
30
|
agentrem snooze <id> --for 2h # Snooze by duration or --until datetime
|
|
31
31
|
agentrem edit <id> # Modify fields
|
|
32
32
|
agentrem stats # Overview (--json for structured output)
|
|
33
|
+
agentrem watch # Background daemon: poll + fire OS notifications
|
|
34
|
+
agentrem doctor # Self-diagnostic check
|
|
35
|
+
agentrem quickstart # Interactive first-run walkthrough
|
|
33
36
|
agentrem setup # Print CLAUDE.md snippet (--mcp for MCP config)
|
|
34
37
|
```
|
|
35
38
|
|
|
@@ -37,7 +40,7 @@ agentrem setup # Print CLAUDE.md snippet (--mcp for MCP config)
|
|
|
37
40
|
|
|
38
41
|
| Type | Use when... | Example |
|
|
39
42
|
|------|------------|---------|
|
|
40
|
-
| `time` | Something is due at a specific time | `--due "
|
|
43
|
+
| `time` | Something is due at a specific time | `--due "+2h"` |
|
|
41
44
|
| `keyword` | You should react when certain words appear | `--trigger keyword --keywords "deploy,release"` |
|
|
42
45
|
| `session` | You need to check every session start | `--trigger session` |
|
|
43
46
|
| `heartbeat` | You need to check every heartbeat | `--trigger heartbeat` |
|
|
@@ -47,6 +50,26 @@ agentrem setup # Print CLAUDE.md snippet (--mcp for MCP config)
|
|
|
47
50
|
|
|
48
51
|
1=Critical (always surfaced), 2=High, 3=Normal, 4=Low (counted not shown), 5=Someday (skipped)
|
|
49
52
|
|
|
53
|
+
## Natural Language Dates
|
|
54
|
+
|
|
55
|
+
`--due` accepts many formats:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
--due "now" # Immediately
|
|
59
|
+
--due "today" # Today at 23:59
|
|
60
|
+
--due "tomorrow" # Tomorrow at 09:00
|
|
61
|
+
--due "in 5 minutes"
|
|
62
|
+
--due "in 2 hours"
|
|
63
|
+
--due "in 3 days"
|
|
64
|
+
--due "in 1 week"
|
|
65
|
+
--due "+5m" # 5 minutes from now
|
|
66
|
+
--due "+2h" # 2 hours from now
|
|
67
|
+
--due "+3d" # 3 days from now
|
|
68
|
+
--due "+1w" # 1 week from now
|
|
69
|
+
--due "2026-02-22T09:00:00"
|
|
70
|
+
--due "2026-02-22"
|
|
71
|
+
```
|
|
72
|
+
|
|
50
73
|
## Agent Integration Patterns
|
|
51
74
|
|
|
52
75
|
```bash
|
|
@@ -65,6 +88,23 @@ agentrem list --json
|
|
|
65
88
|
agentrem stats --json
|
|
66
89
|
```
|
|
67
90
|
|
|
91
|
+
## Background Watcher (watch)
|
|
92
|
+
|
|
93
|
+
`agentrem watch` runs a daemon that polls for due reminders and fires native OS notifications.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
agentrem watch # Start daemon (Ctrl+C to stop)
|
|
97
|
+
agentrem watch --interval 60 # Poll every 60s (default: 30s)
|
|
98
|
+
agentrem watch --agent jarvis # Check for specific agent
|
|
99
|
+
agentrem watch --once # Single check, then exit
|
|
100
|
+
agentrem watch --verbose # Show poll log
|
|
101
|
+
|
|
102
|
+
# Service management (auto-start on boot)
|
|
103
|
+
agentrem watch --install # Install as launchd/systemd service
|
|
104
|
+
agentrem watch --uninstall # Remove service
|
|
105
|
+
agentrem watch --status # Show service status
|
|
106
|
+
```
|
|
107
|
+
|
|
68
108
|
## Key Features
|
|
69
109
|
|
|
70
110
|
- **Recurrence**: `--recur 1d|2w|1m` — auto-creates next on completion
|
|
@@ -74,6 +114,7 @@ agentrem stats --json
|
|
|
74
114
|
- **Multi-agent**: `--agent <name>` isolates per agent
|
|
75
115
|
- **Full-text search**: FTS5 across content, context, tags, notes
|
|
76
116
|
- **JSON output**: `--json` on check, list, search, stats, history
|
|
117
|
+
- **Native notifications**: macOS Agentrem.app with bell icon + priority sounds
|
|
77
118
|
- **MCP server**: `agentrem-mcp` for Claude Desktop / MCP clients
|
|
78
119
|
- **Zero config**: SQLite database, no external services
|
|
79
120
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentrem",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Structured reminders CLI for AI agents with MCP server",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/
|
|
6
|
+
"main": "dist/api.js",
|
|
7
|
+
"types": "dist/api.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/api.js",
|
|
10
|
+
"./mcp": "./dist/mcp/server.js"
|
|
11
|
+
},
|
|
7
12
|
"bin": {
|
|
8
13
|
"agentrem": "dist/index.js",
|
|
9
14
|
"agentrem-mcp": "dist/mcp/server.js"
|
|
@@ -18,6 +23,7 @@
|
|
|
18
23
|
],
|
|
19
24
|
"scripts": {
|
|
20
25
|
"build": "tsc",
|
|
26
|
+
"postbuild": "chmod +x dist/index.js dist/mcp/server.js",
|
|
21
27
|
"build:notify": "bash scripts/build-notify.sh",
|
|
22
28
|
"dev": "tsc --watch",
|
|
23
29
|
"test": "vitest run",
|