@askjo/pi-reflect 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pradeep Elankumaran
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="logo-dark.png" width="300">
4
+ <img src="logo.png" alt="pi-reflect" width="300">
5
+ </picture>
6
+ </p>
7
+
8
+ # pi-reflect
9
+
10
+ Iterative self-improvement for [pi](https://github.com/badlogic/pi-mono) coding agents.
11
+
12
+ Define a target — how your agent should behave, what it should remember, who it should be — and reflect iterates toward it. Each run reads recent conversations and reference material, compares the agent's actual behavior against the target, and makes surgical edits to close the gap.
13
+
14
+ **define the target → reflect reads evidence → edits the file → the agent gets closer.**
15
+
16
+ Works on any markdown file: behavioral rules (`AGENTS.md`), long-term memory (`MEMORY.md`), personality (`SOUL.md`), or anything else.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pi install git:github.com/jo-inc/pi-reflect
22
+ ```
23
+
24
+ Requires pi with an LLM API key configured. Each run makes one LLM call (~$0.05–0.15 with Sonnet).
25
+
26
+ ## Usage
27
+
28
+ ```
29
+ /reflect ./AGENTS.md # run reflection on a file
30
+ /reflect # use saved default target
31
+ /reflect-config # show configured targets
32
+ /reflect-history # show recent runs
33
+ /reflect-stats # correction rate trend + rule recidivism
34
+ /reflect-backfill # bootstrap stats for all historical sessions
35
+ ```
36
+
37
+ First run asks if you want to save the target. After that, just `/reflect`.
38
+
39
+ ## How it works
40
+
41
+ 1. Collects evidence: conversation transcripts, daily logs, reference files — from any combination of sources
42
+ 2. Sends the evidence + the target file + a prompt describing the desired end state to an LLM
43
+ 3. The LLM identifies gaps between actual behavior and the target, proposes surgical edits
44
+ 4. Edits are applied with safety checks: backs up the original, skips ambiguous matches, rejects suspiciously large deletions, auto-commits to git if the target is in a repo
45
+
46
+ Every edit is versioned — reflect auto-commits to git after applying changes, so you get a full history of how each file evolved. `git log AGENTS.md` shows every correction the agent absorbed. `git diff HEAD~5 SOUL.md` shows how the personality sharpened over the last 5 runs.
47
+
48
+ Over time, the file converges: corrections get absorbed as rules, memory accumulates durable facts, personality sharpens from generic to specific. The agent stops needing the same corrections.
49
+
50
+ ## Data sources
51
+
52
+ Each target has two input channels — `transcripts` (what happened) and `context` (reference material). Both accept an array of sources:
53
+
54
+ | Type | Description | Example |
55
+ |------|-------------|---------|
56
+ | `files` | Glob patterns or file paths, pruned by date and size | Daily logs, notes, other markdown files |
57
+ | `command` | Shell command, stdout captured | API calls, database queries, custom scripts |
58
+ | `url` | HTTP GET, response body captured | REST endpoints, health checks |
59
+
60
+ All sources support `{lookbackDays}` interpolation and per-source `maxBytes` caps. File sources are automatically pruned to only include files within the `lookbackDays` window (matched by date in filename).
61
+
62
+ ```json
63
+ {
64
+ "targets": [{
65
+ "path": "/data/me/MEMORY.md",
66
+ "model": "anthropic/claude-sonnet-4-5",
67
+ "lookbackDays": 1,
68
+ "transcripts": [
69
+ { "type": "command", "label": "conversations", "command": "curl -s http://localhost:3001/conversation/recent?days={lookbackDays}", "maxBytes": 400000 }
70
+ ],
71
+ "context": [
72
+ { "type": "files", "label": "daily logs", "paths": ["/data/me/daily/*.md"], "maxBytes": 50000 },
73
+ { "type": "files", "label": "notes", "paths": ["/data/me/notes/*.md"], "maxBytes": 50000 }
74
+ ],
75
+ "prompt": "..."
76
+ }]
77
+ }
78
+ ```
79
+
80
+ For the common case of local pi sessions, just use `transcriptSource`:
81
+
82
+ ```json
83
+ { "transcriptSource": { "type": "pi-sessions" } }
84
+ ```
85
+
86
+ ## Prompts define the target
87
+
88
+ Each target has an optional `prompt` field that tells reflect *what to optimize for*. The same engine drives very different behaviors depending on the prompt:
89
+
90
+ | Target | Prompt goal | What reflect does |
91
+ |--------|------------|-------------------|
92
+ | `AGENTS.md` | Behavioral correctness | Strengthens violated rules, adds rules for recurring patterns |
93
+ | `MEMORY.md` | Factual completeness | Extracts durable facts from conversations, removes stale entries |
94
+ | `SOUL.md` | Identity convergence | Sharpens personality from generic to specific based on interaction patterns |
95
+
96
+ Prompts use `{fileName}`, `{targetContent}`, `{transcripts}`, and `{context}` as placeholders:
97
+
98
+ ```json
99
+ {
100
+ "prompt": "You are evolving an AI identity file ({fileName})...\n\n## Current\n{targetContent}\n\n## Conversations\n{transcripts}\n\n## Reference\n{context}"
101
+ }
102
+ ```
103
+
104
+ If no prompt is set, the default targets behavioral corrections (the original use case).
105
+
106
+ ## Impact Metrics
107
+
108
+ `/reflect-stats` tracks whether reflection is working:
109
+
110
+ - **Correction Rate** — `corrections / sessions` per run, plotted over time. Trending down = the agent is converging.
111
+
112
+ - **Rule Recidivism** — which sections get edited repeatedly. A rule strengthened 3+ times isn't sticking. Sections edited once and never again are resolved.
113
+
114
+ `/reflect-backfill` bootstraps stats from historical sessions (dry-run, no file edits).
115
+
116
+ ## Configuration
117
+
118
+ `~/.pi/agent/reflect.json`:
119
+
120
+ ```json
121
+ {
122
+ "targets": [{
123
+ "path": "/path/to/AGENTS.md",
124
+ "model": "anthropic/claude-sonnet-4-5",
125
+ "lookbackDays": 1,
126
+ "maxSessionBytes": 614400,
127
+ "backupDir": "~/.pi/agent/reflect-backups",
128
+ "transcriptSource": { "type": "pi-sessions" }
129
+ }]
130
+ }
131
+ ```
132
+
133
+ | Field | Default | Description |
134
+ |-------|---------|-------------|
135
+ | `path` | *(required)* | Target markdown file to iterate on |
136
+ | `model` | *(required)* | LLM to use (e.g. `anthropic/claude-sonnet-4-5`) |
137
+ | `lookbackDays` | `1` | How far back to look for evidence |
138
+ | `maxSessionBytes` | `614400` | Max transcript bytes per run |
139
+ | `transcripts` | — | Array of `ContextSource` for transcript data |
140
+ | `transcriptSource` | `pi-sessions` | Legacy single source (use `transcripts` for multiple) |
141
+ | `context` | — | Array of `ContextSource` for reference material |
142
+ | `prompt` | *(default)* | Custom prompt with `{fileName}`, `{targetContent}`, `{transcripts}`, `{context}` |
143
+ | `backupDir` | `~/.pi/agent/reflect-backups` | Where to store pre-edit backups |
144
+
145
+ ## Related
146
+
147
+ - **[pi-mem](https://github.com/jo-inc/pi-mem)** — Memory system for pi agents. Manages MEMORY.md, daily logs, notes, and scratchpad with context injection and keyword search. Pairs naturally with pi-reflect.
148
+
149
+ ## Scheduling
150
+
151
+ ```bash
152
+ pi -p --no-session "/reflect /path/to/AGENTS.md"
153
+ ```
154
+
155
+ Works with cron, launchd, or any scheduler. Ask your pi to set it up for you — there's a [setup guide for agents](SETUP.md).
156
+
157
+ ## Development
158
+
159
+ ```bash
160
+ git clone https://github.com/jo-inc/pi-reflect && cd pi-reflect
161
+ npm install && npm test # 137 tests
162
+ pi -e ./extensions/index.ts # test locally without installing
163
+ ```
164
+
165
+ ## License
166
+
167
+ MIT
package/SETUP.md ADDED
@@ -0,0 +1,168 @@
1
+ # pi-reflect Setup Guide
2
+
3
+ This guide is for you, the coding agent. When a user asks you to "set up reflect", "schedule reflect daily", or "configure pi-reflect", follow these instructions.
4
+
5
+ ## Step 1: Install
6
+
7
+ Run this command:
8
+
9
+ ```bash
10
+ pi install git:github.com/jo-inc/pi-reflect
11
+ ```
12
+
13
+ Then reload extensions:
14
+
15
+ ```
16
+ /reload
17
+ ```
18
+
19
+ ## Step 2: Find the target file
20
+
21
+ The user wants to reflect on a behavioral markdown file — usually `AGENTS.md`, `CLAUDE.md`, `RULES.md`, or similar. Check the current project root and `~/.pi/agent/` for candidates:
22
+
23
+ ```bash
24
+ ls AGENTS.md CLAUDE.md RULES.md .cursorrules .github/copilot-instructions.md 2>/dev/null
25
+ ls ~/.pi/agent/AGENTS.md 2>/dev/null
26
+ ```
27
+
28
+ If nothing exists, ask the user which file they want to improve. If they don't have one yet, suggest creating an `AGENTS.md` in their project root with a few starter rules.
29
+
30
+ ## Step 3: Test it
31
+
32
+ Run reflect once to verify it works:
33
+
34
+ ```
35
+ /reflect /absolute/path/to/AGENTS.md
36
+ ```
37
+
38
+ It will ask if the user wants to save the target. Say yes. This creates `~/.pi/agent/reflect.json`.
39
+
40
+ ## Step 4: Schedule daily runs (optional)
41
+
42
+ If the user wants automatic daily reflection, set up a scheduler. Reflect runs headless via:
43
+
44
+ ```bash
45
+ pi -p --no-session "/reflect"
46
+ ```
47
+
48
+ This uses the saved target from step 3.
49
+
50
+ ### macOS (launchd)
51
+
52
+ Find the pi binary path:
53
+
54
+ ```bash
55
+ which pi
56
+ ```
57
+
58
+ Write the plist — replace `/path/to/pi` with the actual path:
59
+
60
+ ```bash
61
+ cat > ~/Library/LaunchAgents/com.pi.reflect.plist << 'EOF'
62
+ <?xml version="1.0" encoding="UTF-8"?>
63
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
64
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
65
+ <plist version="1.0">
66
+ <dict>
67
+ <key>Label</key>
68
+ <string>com.pi.reflect</string>
69
+ <key>ProgramArguments</key>
70
+ <array>
71
+ <string>PI_PATH</string>
72
+ <string>-p</string>
73
+ <string>--no-session</string>
74
+ <string>/reflect</string>
75
+ </array>
76
+ <key>StartCalendarInterval</key>
77
+ <dict>
78
+ <key>Hour</key>
79
+ <integer>8</integer>
80
+ <key>Minute</key>
81
+ <integer>0</integer>
82
+ </dict>
83
+ <key>StandardOutPath</key>
84
+ <string>/tmp/pi-reflect.log</string>
85
+ <key>StandardErrorPath</key>
86
+ <string>/tmp/pi-reflect.log</string>
87
+ <key>EnvironmentVariables</key>
88
+ <dict>
89
+ <key>PATH</key>
90
+ <string>/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin</string>
91
+ <key>HOME</key>
92
+ <string>HOME_DIR</string>
93
+ </dict>
94
+ </dict>
95
+ </plist>
96
+ EOF
97
+ ```
98
+
99
+ Replace `PI_PATH` and `HOME_DIR` with the actual values using sed:
100
+
101
+ ```bash
102
+ PI_BINARY=$(which pi)
103
+ sed -i '' "s|PI_PATH|$PI_BINARY|g" ~/Library/LaunchAgents/com.pi.reflect.plist
104
+ sed -i '' "s|HOME_DIR|$HOME|g" ~/Library/LaunchAgents/com.pi.reflect.plist
105
+ ```
106
+
107
+ Load it:
108
+
109
+ ```bash
110
+ launchctl load ~/Library/LaunchAgents/com.pi.reflect.plist
111
+ ```
112
+
113
+ ### Linux (cron)
114
+
115
+ ```bash
116
+ PI_BINARY=$(which pi)
117
+ (crontab -l 2>/dev/null; echo "0 8 * * * $PI_BINARY -p --no-session \"/reflect\" >> /tmp/pi-reflect.log 2>&1") | crontab -
118
+ ```
119
+
120
+ ## Step 5: Verify scheduling
121
+
122
+ For macOS:
123
+
124
+ ```bash
125
+ launchctl list | grep pi.reflect
126
+ ```
127
+
128
+ For Linux:
129
+
130
+ ```bash
131
+ crontab -l | grep reflect
132
+ ```
133
+
134
+ Tell the user: reflect is configured. It will run daily at 8am, analyze yesterday's sessions, and update their file. Backups are in `~/.pi/agent/reflect-backups/`. They can check results with `/reflect-history` or `cat /tmp/pi-reflect.log`.
135
+
136
+ ## Configuration reference
137
+
138
+ `~/.pi/agent/reflect.json`:
139
+
140
+ ```json
141
+ {
142
+ "targets": [{
143
+ "path": "/absolute/path/to/AGENTS.md",
144
+ "model": "anthropic/claude-sonnet-4-5",
145
+ "lookbackDays": 1,
146
+ "maxSessionBytes": 614400,
147
+ "backupDir": "~/.pi/agent/reflect-backups",
148
+ "transcriptSource": { "type": "pi-sessions" }
149
+ }]
150
+ }
151
+ ```
152
+
153
+ - **path**: Absolute path to the target file.
154
+ - **model**: Any `provider/model-id` the user has an API key for in pi. Default: `anthropic/claude-sonnet-4-5`.
155
+ - **lookbackDays**: How many days of sessions to analyze. Default: `1`.
156
+ - **maxSessionBytes**: Context budget for transcripts. Default: `614400` (~600KB).
157
+ - **backupDir**: Where backups go before edits. Default: `~/.pi/agent/reflect-backups`.
158
+ - **transcriptSource**: `{ "type": "pi-sessions" }` reads pi's session JSONL files. `{ "type": "command", "command": "script {lookbackDays}" }` runs a custom command instead.
159
+
160
+ Multiple targets are supported — add more objects to the `targets` array.
161
+
162
+ ## Troubleshooting
163
+
164
+ - **"No API key for model"**: The user needs to configure an API key for the model in pi. Run `/model` to check available models.
165
+ - **"No substantive sessions found"**: No sessions with 3+ exchanges found in the lookback period. Try increasing `lookbackDays`.
166
+ - **"Target file too small"**: The file must be at least 100 bytes. It needs some existing rules for reflect to work with.
167
+ - **Edits skipped**: Reflect logs the reason for each skip (ambiguous match, text not found, already exists). This is a safety feature, not a bug.
168
+ - **launchd not running**: Check `launchctl list | grep pi.reflect`. If missing, `launchctl load` the plist. Check `/tmp/pi-reflect.log` for errors. Common issue: PATH doesn't include the directory where `pi` and `node` are installed.