@mariozechner/pi-mom 0.20.2 → 0.22.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 +141 -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
|
|
|
@@ -13,6 +13,13 @@ A Slack bot powered by Claude that can execute bash commands, read/write files,
|
|
|
13
13
|
- **Working Memory & Custom Tools**: Mom remembers context across sessions and creates workflow-specific CLI tools ([aka "skills"](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/)) for your tasks
|
|
14
14
|
- **Thread-Based Details**: Clean main messages with verbose tool details in threads
|
|
15
15
|
|
|
16
|
+
## Documentation
|
|
17
|
+
|
|
18
|
+
- [Artifacts Server](docs/artifacts-server.md) - Share HTML/JS visualizations publicly with live reload
|
|
19
|
+
- [Events System](docs/events.md) - Schedule reminders and periodic tasks
|
|
20
|
+
- [Sandbox Guide](docs/sandbox.md) - Docker vs host mode security
|
|
21
|
+
- [Slack Bot Setup](docs/slack-bot-minimal-guide.md) - Minimal Slack integration guide
|
|
22
|
+
|
|
16
23
|
## Installation
|
|
17
24
|
|
|
18
25
|
```bash
|
|
@@ -94,18 +101,30 @@ Options:
|
|
|
94
101
|
|
|
95
102
|
## How Mom Works
|
|
96
103
|
|
|
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
|
|
104
|
+
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
105
|
|
|
99
|
-
|
|
106
|
+
**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
107
|
|
|
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
|
|
108
|
+
**When a message arrives in a channel:**
|
|
109
|
+
- The message is written to the channel's `log.jsonl`, retaining full channel history
|
|
110
|
+
- If the message has attachments, they are stored in the channel's `attachments/` folder for mom to access
|
|
111
|
+
- Mom can later search the `log.jsonl` file for previous conversations and reference the attachments
|
|
107
112
|
|
|
108
|
-
|
|
113
|
+
**When you @mention mom (or DM her), she:**
|
|
114
|
+
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
|
|
115
|
+
2. Loads **memory** from MEMORY.md files (global and channel-specific)
|
|
116
|
+
3. Responds to your request, dynamically using tools to answer it:
|
|
117
|
+
- Read attachments and analyze them
|
|
118
|
+
- Invoke command line tools, e.g. to read your emails
|
|
119
|
+
- Write new files or programs
|
|
120
|
+
- Attach files to her response
|
|
121
|
+
4. Any files or tools mom creates are stored in the channel's directory
|
|
122
|
+
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
|
|
123
|
+
|
|
124
|
+
**Context Management:**
|
|
125
|
+
- 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
|
|
126
|
+
- 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
|
|
127
|
+
- For older history beyond context, mom can grep `log.jsonl` for infinite searchable history
|
|
109
128
|
|
|
110
129
|
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
130
|
|
|
@@ -164,7 +183,7 @@ You provide mom with a **data directory** (e.g., `./data`) as her workspace. Whi
|
|
|
164
183
|
|
|
165
184
|
**What's stored here:**
|
|
166
185
|
- `log.jsonl`: All channel messages (user messages, bot responses). Source of truth.
|
|
167
|
-
- `context.jsonl`: Messages sent to
|
|
186
|
+
- `context.jsonl`: Messages sent to the LLM. Synced from log.jsonl at each run start.
|
|
168
187
|
- Memory files: Context mom remembers across sessions
|
|
169
188
|
- Custom tools/scripts mom creates (aka "skills")
|
|
170
189
|
- Working files, cloned repos, generated output
|
|
@@ -173,13 +192,110 @@ Mom efficiently greps `log.jsonl` for conversation history, giving her essential
|
|
|
173
192
|
|
|
174
193
|
### Memory
|
|
175
194
|
|
|
176
|
-
Mom
|
|
177
|
-
- **Global memory** (`data/MEMORY.md`): Shared across all channels.
|
|
195
|
+
Mom uses MEMORY.md files to remember basic rules and preferences:
|
|
196
|
+
- **Global memory** (`data/MEMORY.md`): Shared across all channels. Project architecture, coding conventions, communication preferences
|
|
178
197
|
- **Channel memory** (`data/<channel>/MEMORY.md`): Channel-specific context, decisions, ongoing work
|
|
179
198
|
|
|
180
199
|
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
200
|
|
|
182
|
-
Memory files typically contain
|
|
201
|
+
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.
|
|
202
|
+
|
|
203
|
+
### Skills
|
|
204
|
+
|
|
205
|
+
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.
|
|
206
|
+
|
|
207
|
+
Skills are stored in:
|
|
208
|
+
- `/workspace/skills/`: Global tools available everywhere
|
|
209
|
+
- `/workspace/<channel>/skills/`: Channel-specific tools
|
|
210
|
+
|
|
211
|
+
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:
|
|
212
|
+
|
|
213
|
+
```markdown
|
|
214
|
+
---
|
|
215
|
+
name: gmail
|
|
216
|
+
description: Read, search, and send Gmail via IMAP/SMTP
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
# Gmail Skill
|
|
220
|
+
...
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
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.
|
|
224
|
+
|
|
225
|
+
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.
|
|
226
|
+
|
|
227
|
+
#### Creating a Skill
|
|
228
|
+
|
|
229
|
+
You can ask mom to create skills for you. For example:
|
|
230
|
+
|
|
231
|
+
> "Create a skill that lets me manage a simple notes file. I should be able to add notes, read all notes, and clear them."
|
|
232
|
+
|
|
233
|
+
Mom would create something like `/workspace/skills/note/SKILL.md`:
|
|
234
|
+
|
|
235
|
+
```markdown
|
|
236
|
+
---
|
|
237
|
+
name: note
|
|
238
|
+
description: Add and read notes from a persistent notes file
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
# Note Skill
|
|
242
|
+
|
|
243
|
+
Manage a simple notes file with timestamps.
|
|
244
|
+
|
|
245
|
+
## Usage
|
|
246
|
+
|
|
247
|
+
Add a note:
|
|
248
|
+
\`\`\`bash
|
|
249
|
+
bash {baseDir}/note.sh add "Buy groceries"
|
|
250
|
+
\`\`\`
|
|
251
|
+
|
|
252
|
+
Read all notes:
|
|
253
|
+
\`\`\`bash
|
|
254
|
+
bash {baseDir}/note.sh read
|
|
255
|
+
\`\`\`
|
|
256
|
+
|
|
257
|
+
Search notes by keyword:
|
|
258
|
+
\`\`\`bash
|
|
259
|
+
grep -i "groceries" ~/.notes.txt
|
|
260
|
+
\`\`\`
|
|
261
|
+
|
|
262
|
+
Search notes by date (format: YYYY-MM-DD):
|
|
263
|
+
\`\`\`bash
|
|
264
|
+
grep "2025-12-13" ~/.notes.txt
|
|
265
|
+
\`\`\`
|
|
266
|
+
|
|
267
|
+
Clear all notes:
|
|
268
|
+
\`\`\`bash
|
|
269
|
+
bash {baseDir}/note.sh clear
|
|
270
|
+
\`\`\`
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
And `/workspace/skills/note/note.sh`:
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
#!/bin/bash
|
|
277
|
+
NOTES_FILE="$HOME/.notes.txt"
|
|
278
|
+
|
|
279
|
+
case "$1" in
|
|
280
|
+
add)
|
|
281
|
+
echo "[$(date -Iseconds)] $2" >> "$NOTES_FILE"
|
|
282
|
+
echo "Note added"
|
|
283
|
+
;;
|
|
284
|
+
read)
|
|
285
|
+
cat "$NOTES_FILE" 2>/dev/null || echo "No notes yet"
|
|
286
|
+
;;
|
|
287
|
+
clear)
|
|
288
|
+
rm -f "$NOTES_FILE"
|
|
289
|
+
echo "Notes cleared"
|
|
290
|
+
;;
|
|
291
|
+
*)
|
|
292
|
+
echo "Usage: note.sh {add|read|clear}"
|
|
293
|
+
exit 1
|
|
294
|
+
;;
|
|
295
|
+
esac
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
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
299
|
|
|
184
300
|
### Events (Scheduled Wake-ups)
|
|
185
301
|
|
|
@@ -231,122 +347,25 @@ You can write event files directly to `data/events/` on the host machine. This l
|
|
|
231
347
|
|
|
232
348
|
**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
349
|
|
|
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
350
|
### Updating Mom
|
|
312
351
|
|
|
313
352
|
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
353
|
|
|
315
354
|
## Message History
|
|
316
355
|
|
|
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)
|
|
356
|
+
Mom uses two files per channel to manage conversation history:
|
|
343
357
|
|
|
344
|
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
347
|
-
-
|
|
358
|
+
**log.jsonl** ([format](../../src/store.ts)) (source of truth):
|
|
359
|
+
- All messages from users and mom (no tool results)
|
|
360
|
+
- Custom JSONL format with timestamps, user info, text, attachments
|
|
361
|
+
- Append-only, never compacted
|
|
362
|
+
- Used for syncing to context and searching older history
|
|
348
363
|
|
|
349
|
-
|
|
364
|
+
**context.jsonl** ([format](../../src/context.ts)) (LLM context):
|
|
365
|
+
- What's sent to the LLM (includes tool results and full history)
|
|
366
|
+
- Auto-synced from `log.jsonl` before each @mention (picks up backfilled messages, channel chatter)
|
|
367
|
+
- 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
|
|
368
|
+
- Mom can grep `log.jsonl` for older history beyond what's in context
|
|
350
369
|
|
|
351
370
|
## Security Considerations
|
|
352
371
|
|
|
@@ -451,14 +470,6 @@ cd packages/mom
|
|
|
451
470
|
npx tsx --watch-path src --watch src/main.ts --sandbox=docker:mom-sandbox ./data
|
|
452
471
|
```
|
|
453
472
|
|
|
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
473
|
## License
|
|
463
474
|
|
|
464
475
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mariozechner/pi-mom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.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.22.0",
|
|
25
|
+
"@mariozechner/pi-ai": "^0.22.0",
|
|
26
|
+
"@mariozechner/pi-coding-agent": "^0.22.0",
|
|
27
27
|
"@sinclair/typebox": "^0.34.0",
|
|
28
28
|
"@slack/socket-mode": "^2.0.0",
|
|
29
29
|
"@slack/web-api": "^7.0.0",
|