@mariozechner/pi-mom 0.20.2 → 0.21.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/CHANGELOG.md +2 -0
- package/README.md +134 -130
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# mom (Master Of Mischief)
|
|
2
2
|
|
|
3
|
-
A Slack bot powered by
|
|
3
|
+
A Slack bot powered by an LLM that can execute bash commands, read/write files, and interact with your development environment. Mom is **self-managing**. She installs her own tools, programs [CLI tools (aka "skills")](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/) she can use to help with your workflows and tasks, configures credentials, and maintains her workspace autonomously.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -94,18 +94,30 @@ Options:
|
|
|
94
94
|
|
|
95
95
|
## How Mom Works
|
|
96
96
|
|
|
97
|
-
Mom is a Node.js app that runs on your host machine. She connects to Slack via Socket Mode, receives messages, and responds using
|
|
97
|
+
Mom is a Node.js app that runs on your host machine. She connects to Slack via Socket Mode, receives messages, and responds using an LLM-based agent that can create and use tools.
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
**For each channel you add mom to** (group channels or DMs), mom maintains a separate conversation history with its own context, memory, and files.
|
|
100
100
|
|
|
101
|
-
When
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
4. Stores everything in the **data directory**. This includes conversation logs, files, and custom CLI tools (**skills**)
|
|
106
|
-
5. Responds with results
|
|
101
|
+
**When a message arrives in a channel:**
|
|
102
|
+
- The message is written to the channel's `log.jsonl`, retaining full channel history
|
|
103
|
+
- If the message has attachments, they are stored in the channel's `attachments/` folder for mom to access
|
|
104
|
+
- Mom can later search the `log.jsonl` file for previous conversations and reference the attachments
|
|
107
105
|
|
|
108
|
-
|
|
106
|
+
**When you @mention mom (or DM her), she:**
|
|
107
|
+
1. Syncs all unseen messages from `log.jsonl` into `context.jsonl`. The context is what mom actually sees in terms of content when she responds
|
|
108
|
+
2. Loads **memory** from MEMORY.md files (global and channel-specific)
|
|
109
|
+
3. Responds to your request, dynamically using tools to answer it:
|
|
110
|
+
- Read attachments and analyze them
|
|
111
|
+
- Invoke command line tools, e.g. to read your emails
|
|
112
|
+
- Write new files or programs
|
|
113
|
+
- Attach files to her response
|
|
114
|
+
4. Any files or tools mom creates are stored in the channel's directory
|
|
115
|
+
5. Mom's direct reply is stored in `log.jsonl`, while details like tool call results are kept in `context.jsonl` which she'll see and thus "remember" on subsequent requests
|
|
116
|
+
|
|
117
|
+
**Context Management:**
|
|
118
|
+
- Mom has limited context depending on the LLM model used. E.g. Claude Opus or Sonnet 4.5 can process a maximum of 200k tokens
|
|
119
|
+
- When the context exceeds the LLM's context window size, mom compacts the context: keeps recent messages and tool results in full, summarizes older ones
|
|
120
|
+
- For older history beyond context, mom can grep `log.jsonl` for infinite searchable history
|
|
109
121
|
|
|
110
122
|
Everything mom does happens in a workspace you control. This is a single directory that's the only directory she can access on your host machine (when in Docker mode). You can inspect logs, memory, and tools she creates anytime.
|
|
111
123
|
|
|
@@ -164,7 +176,7 @@ You provide mom with a **data directory** (e.g., `./data`) as her workspace. Whi
|
|
|
164
176
|
|
|
165
177
|
**What's stored here:**
|
|
166
178
|
- `log.jsonl`: All channel messages (user messages, bot responses). Source of truth.
|
|
167
|
-
- `context.jsonl`: Messages sent to
|
|
179
|
+
- `context.jsonl`: Messages sent to the LLM. Synced from log.jsonl at each run start.
|
|
168
180
|
- Memory files: Context mom remembers across sessions
|
|
169
181
|
- Custom tools/scripts mom creates (aka "skills")
|
|
170
182
|
- Working files, cloned repos, generated output
|
|
@@ -173,13 +185,110 @@ Mom efficiently greps `log.jsonl` for conversation history, giving her essential
|
|
|
173
185
|
|
|
174
186
|
### Memory
|
|
175
187
|
|
|
176
|
-
Mom
|
|
177
|
-
- **Global memory** (`data/MEMORY.md`): Shared across all channels.
|
|
188
|
+
Mom uses MEMORY.md files to remember basic rules and preferences:
|
|
189
|
+
- **Global memory** (`data/MEMORY.md`): Shared across all channels. Project architecture, coding conventions, communication preferences
|
|
178
190
|
- **Channel memory** (`data/<channel>/MEMORY.md`): Channel-specific context, decisions, ongoing work
|
|
179
191
|
|
|
180
192
|
Mom automatically reads these files before responding. You can ask her to update memory ("remember that we use tabs not spaces") or edit the files directly yourself.
|
|
181
193
|
|
|
182
|
-
Memory files typically contain
|
|
194
|
+
Memory files typically contain email writing tone preferences, coding conventions, team member responsibilities, common troubleshooting steps, and workflow patterns. Basically anything describing how you and your team work.
|
|
195
|
+
|
|
196
|
+
### Skills
|
|
197
|
+
|
|
198
|
+
Mom can install and use standard CLI tools (like GitHub CLI, npm packages, etc.). Mom can also write custom tools for your specific needs, which are called skills.
|
|
199
|
+
|
|
200
|
+
Skills are stored in:
|
|
201
|
+
- `/workspace/skills/`: Global tools available everywhere
|
|
202
|
+
- `/workspace/<channel>/skills/`: Channel-specific tools
|
|
203
|
+
|
|
204
|
+
Each skill has a `SKILL.md` file with frontmatter and detailed usage instructions, plus any scripts or programs mom needs to use the skill. The frontmatter defines the skill's name and a brief description:
|
|
205
|
+
|
|
206
|
+
```markdown
|
|
207
|
+
---
|
|
208
|
+
name: gmail
|
|
209
|
+
description: Read, search, and send Gmail via IMAP/SMTP
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
# Gmail Skill
|
|
213
|
+
...
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
When mom responds, she's given the names, descriptions, and file locations of all `SKILL.md` files in `/workspace/skills/` and `/workspace/<channel>/skills/`, so she knows what's available to handle your request. When mom decides to use a skill, she reads the `SKILL.md` in full, after which she's able to use the skill by invoking its scripts and programs.
|
|
217
|
+
|
|
218
|
+
You can find a set of basic skills at <https://github.com/badlogic/pi-skills|github.com/badlogic/pi-skills>. Just tell mom to clone this repository into `/workspace/skills/pi-skills` and she'll help you set up the rest.
|
|
219
|
+
|
|
220
|
+
#### Creating a Skill
|
|
221
|
+
|
|
222
|
+
You can ask mom to create skills for you. For example:
|
|
223
|
+
|
|
224
|
+
> "Create a skill that lets me manage a simple notes file. I should be able to add notes, read all notes, and clear them."
|
|
225
|
+
|
|
226
|
+
Mom would create something like `/workspace/skills/note/SKILL.md`:
|
|
227
|
+
|
|
228
|
+
```markdown
|
|
229
|
+
---
|
|
230
|
+
name: note
|
|
231
|
+
description: Add and read notes from a persistent notes file
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
# Note Skill
|
|
235
|
+
|
|
236
|
+
Manage a simple notes file with timestamps.
|
|
237
|
+
|
|
238
|
+
## Usage
|
|
239
|
+
|
|
240
|
+
Add a note:
|
|
241
|
+
\`\`\`bash
|
|
242
|
+
bash {baseDir}/note.sh add "Buy groceries"
|
|
243
|
+
\`\`\`
|
|
244
|
+
|
|
245
|
+
Read all notes:
|
|
246
|
+
\`\`\`bash
|
|
247
|
+
bash {baseDir}/note.sh read
|
|
248
|
+
\`\`\`
|
|
249
|
+
|
|
250
|
+
Search notes by keyword:
|
|
251
|
+
\`\`\`bash
|
|
252
|
+
grep -i "groceries" ~/.notes.txt
|
|
253
|
+
\`\`\`
|
|
254
|
+
|
|
255
|
+
Search notes by date (format: YYYY-MM-DD):
|
|
256
|
+
\`\`\`bash
|
|
257
|
+
grep "2025-12-13" ~/.notes.txt
|
|
258
|
+
\`\`\`
|
|
259
|
+
|
|
260
|
+
Clear all notes:
|
|
261
|
+
\`\`\`bash
|
|
262
|
+
bash {baseDir}/note.sh clear
|
|
263
|
+
\`\`\`
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
And `/workspace/skills/note/note.sh`:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
#!/bin/bash
|
|
270
|
+
NOTES_FILE="$HOME/.notes.txt"
|
|
271
|
+
|
|
272
|
+
case "$1" in
|
|
273
|
+
add)
|
|
274
|
+
echo "[$(date -Iseconds)] $2" >> "$NOTES_FILE"
|
|
275
|
+
echo "Note added"
|
|
276
|
+
;;
|
|
277
|
+
read)
|
|
278
|
+
cat "$NOTES_FILE" 2>/dev/null || echo "No notes yet"
|
|
279
|
+
;;
|
|
280
|
+
clear)
|
|
281
|
+
rm -f "$NOTES_FILE"
|
|
282
|
+
echo "Notes cleared"
|
|
283
|
+
;;
|
|
284
|
+
*)
|
|
285
|
+
echo "Usage: note.sh {add|read|clear}"
|
|
286
|
+
exit 1
|
|
287
|
+
;;
|
|
288
|
+
esac
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Now, if you ask mom to "take a note: buy groceries", she'll use the note skill to add it. Ask her to "show me my notes" and she'll read them back to you.
|
|
183
292
|
|
|
184
293
|
### Events (Scheduled Wake-ups)
|
|
185
294
|
|
|
@@ -231,122 +340,25 @@ You can write event files directly to `data/events/` on the host machine. This l
|
|
|
231
340
|
|
|
232
341
|
**Example workflow:** Ask mom to "remind me about the dentist tomorrow at 9am" and she'll create a one-shot event. Ask her to "check my inbox every morning at 9" and she'll create a periodic event with cron schedule `0 9 * * *`.
|
|
233
342
|
|
|
234
|
-
### Custom CLI Tools ("Skills")
|
|
235
|
-
|
|
236
|
-
Mom can write custom CLI tools to help with recurring tasks, access specific systems like email, calendars, web search, CRM/CMS platforms, issue trackers, Notion, project management tools, or process data (generate charts, Excel sheets, reports, etc.). You can attach files and ask her to process them with a skill, or let her pick the right tool for the task. These "skills" are stored in:
|
|
237
|
-
- `data/skills/`: Global tools available everywhere
|
|
238
|
-
- `data/<channel>/skills/`: Channel-specific tools
|
|
239
|
-
|
|
240
|
-
**Skills are auto-discovered.** Each skill directory must contain a `SKILL.md` file with YAML frontmatter:
|
|
241
|
-
|
|
242
|
-
```markdown
|
|
243
|
-
---
|
|
244
|
-
description: Read, search, and send Gmail via IMAP/SMTP
|
|
245
|
-
name: gmail
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
# Gmail Skill
|
|
249
|
-
|
|
250
|
-
## Setup
|
|
251
|
-
Run `node gmail.js setup` and enter your Gmail app password.
|
|
252
|
-
|
|
253
|
-
## Usage
|
|
254
|
-
\`\`\`bash
|
|
255
|
-
node {baseDir}/gmail.js search --unread --limit 10
|
|
256
|
-
node {baseDir}/gmail.js read 12345
|
|
257
|
-
node {baseDir}/gmail.js send --to "user@example.com" --subject "Hello" --body "Message"
|
|
258
|
-
\`\`\`
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
**Frontmatter fields:**
|
|
262
|
-
|
|
263
|
-
| Field | Required | Description |
|
|
264
|
-
|-------|----------|-------------|
|
|
265
|
-
| `description` | Yes | Short description shown in mom's system prompt |
|
|
266
|
-
| `name` | No | Override skill name (defaults to directory name) |
|
|
267
|
-
|
|
268
|
-
**Variables:**
|
|
269
|
-
|
|
270
|
-
Use `{baseDir}` as a placeholder for the skill's directory path. Mom substitutes the actual path when reading the skill.
|
|
271
|
-
|
|
272
|
-
**How it works:**
|
|
273
|
-
|
|
274
|
-
Mom sees available skills listed in her system prompt with their descriptions. When a task matches a skill, she reads the full `SKILL.md` to get usage instructions.
|
|
275
|
-
|
|
276
|
-
**Skill directory structure:**
|
|
277
|
-
```
|
|
278
|
-
data/skills/gmail/
|
|
279
|
-
├── SKILL.md # Required: frontmatter + instructions
|
|
280
|
-
├── gmail.js # Tool implementation
|
|
281
|
-
├── config.json # Credentials (created on first use)
|
|
282
|
-
└── package.json # Dependencies (if Node.js)
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
You develop skills together with mom. Tell her what you need and she'll create the tools accordingly. Knowing how to program and how to steer coding agents helps with this task. Ask a friendly neighborhood programmer if you get stuck. Most tools take 5-10 minutes to create. You can even put them in a git repo for versioning and reuse across different mom instances.
|
|
286
|
-
|
|
287
|
-
**Real-world examples:**
|
|
288
|
-
|
|
289
|
-
**Gmail**:
|
|
290
|
-
```bash
|
|
291
|
-
node gmail.js search --unread --limit 10
|
|
292
|
-
node gmail.js read 12345
|
|
293
|
-
node gmail.js send --to "user@example.com" --subject "Hello" --text "Message"
|
|
294
|
-
```
|
|
295
|
-
Mom creates a Node.js CLI that uses IMAP/SMTP, asks for your Gmail app password, stores it in `config.json`, and can now read/search/send emails. Supports multiple accounts.
|
|
296
|
-
|
|
297
|
-
**Transcribe**:
|
|
298
|
-
```bash
|
|
299
|
-
bash transcribe.sh /path/to/voice_memo.m4a
|
|
300
|
-
```
|
|
301
|
-
Mom creates a Bash script that submits audio to Groq's Whisper API, asks for your API key once, stores it in the script, and transcribes voice memos you attach to messages.
|
|
302
|
-
|
|
303
|
-
**Fetch Content**:
|
|
304
|
-
```bash
|
|
305
|
-
node fetch-content.js https://example.com/article
|
|
306
|
-
```
|
|
307
|
-
Mom creates a Node.js tool that fetches URLs and extracts readable content as markdown. No API key needed. Works for articles, docs, Wikipedia.
|
|
308
|
-
|
|
309
|
-
Mom automatically discovers skills and lists them in her system prompt. She reads the `SKILL.md` before using a skill and reuses stored credentials automatically.
|
|
310
|
-
|
|
311
343
|
### Updating Mom
|
|
312
344
|
|
|
313
345
|
Update mom anytime with `npm install -g @mariozechner/pi-mom`. This only updates the Node.js app on your host. Anything mom installed inside the Docker container remains unchanged.
|
|
314
346
|
|
|
315
347
|
## Message History
|
|
316
348
|
|
|
317
|
-
Mom uses two files per channel to manage
|
|
318
|
-
|
|
319
|
-
### log.jsonl (Source of Truth)
|
|
320
|
-
|
|
321
|
-
All channel messages are stored here. This includes user messages, channel chatter (messages without @mention), and bot responses. Format: one JSON object per line with ISO 8601 timestamps:
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
interface LoggedMessage {
|
|
325
|
-
date: string; // ISO 8601 (e.g., "2025-11-26T10:44:00.000Z")
|
|
326
|
-
ts: string; // Slack timestamp (seconds.microseconds)
|
|
327
|
-
user: string; // User ID or "bot"
|
|
328
|
-
userName?: string; // Handle (e.g., "mario")
|
|
329
|
-
displayName?: string; // Display name (e.g., "Mario Zechner")
|
|
330
|
-
text: string; // Message text (@mentions stripped)
|
|
331
|
-
attachments: string[]; // Filenames of attachments
|
|
332
|
-
isBot: boolean;
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
**Example:**
|
|
337
|
-
```json
|
|
338
|
-
{"date":"2025-11-26T10:44:00.123Z","ts":"1732619040.123456","user":"U123ABC","userName":"mario","text":"hello","attachments":[],"isBot":false}
|
|
339
|
-
{"date":"2025-11-26T10:44:05.456Z","ts":"1732619045456","user":"bot","text":"Hi! How can I help?","attachments":[],"isBot":true}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### context.jsonl (LLM Context)
|
|
349
|
+
Mom uses two files per channel to manage conversation history:
|
|
343
350
|
|
|
344
|
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
347
|
-
-
|
|
351
|
+
**log.jsonl** ([format](../../src/store.ts)) (source of truth):
|
|
352
|
+
- All messages from users and mom (no tool results)
|
|
353
|
+
- Custom JSONL format with timestamps, user info, text, attachments
|
|
354
|
+
- Append-only, never compacted
|
|
355
|
+
- Used for syncing to context and searching older history
|
|
348
356
|
|
|
349
|
-
|
|
357
|
+
**context.jsonl** ([format](../../src/context.ts)) (LLM context):
|
|
358
|
+
- What's sent to the LLM (includes tool results and full history)
|
|
359
|
+
- Auto-synced from `log.jsonl` before each @mention (picks up backfilled messages, channel chatter)
|
|
360
|
+
- When context exceeds the LLM's context window size, mom compacts it: keeps recent messages and tool results in full, summarizes older ones into a compaction event. On subsequent requests, the LLM gets the summary + recent messages from the compaction point onward
|
|
361
|
+
- Mom can grep `log.jsonl` for older history beyond what's in context
|
|
350
362
|
|
|
351
363
|
## Security Considerations
|
|
352
364
|
|
|
@@ -451,14 +463,6 @@ cd packages/mom
|
|
|
451
463
|
npx tsx --watch-path src --watch src/main.ts --sandbox=docker:mom-sandbox ./data
|
|
452
464
|
```
|
|
453
465
|
|
|
454
|
-
### Key Concepts
|
|
455
|
-
|
|
456
|
-
- **SlackContext**: Per-message context with respond/setWorking/replaceMessage methods
|
|
457
|
-
- **AgentRunner**: Returns `{ stopReason }`. Never throws for normal flow
|
|
458
|
-
- **Working Indicator**: "..." appended while processing, removed on completion
|
|
459
|
-
- **Memory System**: MEMORY.md files loaded into system prompt automatically
|
|
460
|
-
- **Prompt Caching**: Recent messages in user prompt (not system) for better cache hits
|
|
461
|
-
|
|
462
466
|
## License
|
|
463
467
|
|
|
464
468
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi-mom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Slack bot that delegates messages to the pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@anthropic-ai/sandbox-runtime": "^0.0.16",
|
|
24
|
-
"@mariozechner/pi-agent-core": "^0.
|
|
25
|
-
"@mariozechner/pi-ai": "^0.
|
|
26
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
24
|
+
"@mariozechner/pi-agent-core": "^0.21.0",
|
|
25
|
+
"@mariozechner/pi-ai": "^0.21.0",
|
|
26
|
+
"@mariozechner/pi-coding-agent": "^0.21.0",
|
|
27
27
|
"@sinclair/typebox": "^0.34.0",
|
|
28
28
|
"@slack/socket-mode": "^2.0.0",
|
|
29
29
|
"@slack/web-api": "^7.0.0",
|