pi-continuous-learning 0.3.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 +21 -0
- package/README.md +326 -0
- package/dist/active-instincts.d.ts +4 -0
- package/dist/active-instincts.d.ts.map +1 -0
- package/dist/active-instincts.js +11 -0
- package/dist/active-instincts.js.map +1 -0
- package/dist/agents-md.d.ts +12 -0
- package/dist/agents-md.d.ts.map +1 -0
- package/dist/agents-md.js +23 -0
- package/dist/agents-md.js.map +1 -0
- package/dist/cli/analyze-prompt.d.ts +2 -0
- package/dist/cli/analyze-prompt.d.ts.map +1 -0
- package/dist/cli/analyze-prompt.js +72 -0
- package/dist/cli/analyze-prompt.js.map +1 -0
- package/dist/cli/analyze.d.ts +3 -0
- package/dist/cli/analyze.d.ts.map +1 -0
- package/dist/cli/analyze.js +214 -0
- package/dist/cli/analyze.js.map +1 -0
- package/dist/confidence.d.ts +25 -0
- package/dist/confidence.d.ts.map +1 -0
- package/dist/confidence.js +77 -0
- package/dist/confidence.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +89 -0
- package/dist/config.js.map +1 -0
- package/dist/error-logger.d.ts +34 -0
- package/dist/error-logger.d.ts.map +1 -0
- package/dist/error-logger.js +102 -0
- package/dist/error-logger.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/instinct-decay.d.ts +39 -0
- package/dist/instinct-decay.d.ts.map +1 -0
- package/dist/instinct-decay.js +93 -0
- package/dist/instinct-decay.js.map +1 -0
- package/dist/instinct-evolve.d.ts +5 -0
- package/dist/instinct-evolve.d.ts.map +1 -0
- package/dist/instinct-evolve.js +24 -0
- package/dist/instinct-evolve.js.map +1 -0
- package/dist/instinct-export.d.ts +40 -0
- package/dist/instinct-export.d.ts.map +1 -0
- package/dist/instinct-export.js +94 -0
- package/dist/instinct-export.js.map +1 -0
- package/dist/instinct-import.d.ts +50 -0
- package/dist/instinct-import.d.ts.map +1 -0
- package/dist/instinct-import.js +168 -0
- package/dist/instinct-import.js.map +1 -0
- package/dist/instinct-injector.d.ts +39 -0
- package/dist/instinct-injector.d.ts.map +1 -0
- package/dist/instinct-injector.js +89 -0
- package/dist/instinct-injector.js.map +1 -0
- package/dist/instinct-loader.d.ts +37 -0
- package/dist/instinct-loader.d.ts.map +1 -0
- package/dist/instinct-loader.js +96 -0
- package/dist/instinct-loader.js.map +1 -0
- package/dist/instinct-parser.d.ts +28 -0
- package/dist/instinct-parser.d.ts.map +1 -0
- package/dist/instinct-parser.js +143 -0
- package/dist/instinct-parser.js.map +1 -0
- package/dist/instinct-projects.d.ts +32 -0
- package/dist/instinct-projects.d.ts.map +1 -0
- package/dist/instinct-projects.js +96 -0
- package/dist/instinct-projects.js.map +1 -0
- package/dist/instinct-promote.d.ts +51 -0
- package/dist/instinct-promote.d.ts.map +1 -0
- package/dist/instinct-promote.js +169 -0
- package/dist/instinct-promote.js.map +1 -0
- package/dist/instinct-status.d.ts +39 -0
- package/dist/instinct-status.d.ts.map +1 -0
- package/dist/instinct-status.js +108 -0
- package/dist/instinct-status.js.map +1 -0
- package/dist/instinct-store.d.ts +30 -0
- package/dist/instinct-store.d.ts.map +1 -0
- package/dist/instinct-store.js +118 -0
- package/dist/instinct-store.js.map +1 -0
- package/dist/instinct-tools.d.ts +161 -0
- package/dist/instinct-tools.d.ts.map +1 -0
- package/dist/instinct-tools.js +240 -0
- package/dist/instinct-tools.js.map +1 -0
- package/dist/observations.d.ts +22 -0
- package/dist/observations.d.ts.map +1 -0
- package/dist/observations.js +62 -0
- package/dist/observations.js.map +1 -0
- package/dist/observer-guard.d.ts +3 -0
- package/dist/observer-guard.d.ts.map +1 -0
- package/dist/observer-guard.js +13 -0
- package/dist/observer-guard.js.map +1 -0
- package/dist/project.d.ts +16 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +59 -0
- package/dist/project.js.map +1 -0
- package/dist/prompt-observer.d.ts +25 -0
- package/dist/prompt-observer.d.ts.map +1 -0
- package/dist/prompt-observer.js +63 -0
- package/dist/prompt-observer.js.map +1 -0
- package/dist/prompts/analyzer-user.d.ts +38 -0
- package/dist/prompts/analyzer-user.d.ts.map +1 -0
- package/dist/prompts/analyzer-user.js +105 -0
- package/dist/prompts/analyzer-user.js.map +1 -0
- package/dist/prompts/evolve-prompt.d.ts +3 -0
- package/dist/prompts/evolve-prompt.d.ts.map +1 -0
- package/dist/prompts/evolve-prompt.js +51 -0
- package/dist/prompts/evolve-prompt.js.map +1 -0
- package/dist/scrubber.d.ts +9 -0
- package/dist/scrubber.d.ts.map +1 -0
- package/dist/scrubber.js +40 -0
- package/dist/scrubber.js.map +1 -0
- package/dist/storage.d.ts +22 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +71 -0
- package/dist/storage.js.map +1 -0
- package/dist/tool-observer.d.ts +32 -0
- package/dist/tool-observer.d.ts.map +1 -0
- package/dist/tool-observer.js +77 -0
- package/dist/tool-observer.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +66 -0
- package/src/active-instincts.ts +13 -0
- package/src/agents-md.ts +23 -0
- package/src/cli/analyze-prompt.ts +71 -0
- package/src/cli/analyze.ts +286 -0
- package/src/confidence.ts +103 -0
- package/src/config.ts +111 -0
- package/src/error-logger.ts +130 -0
- package/src/index.ts +144 -0
- package/src/instinct-decay.ts +117 -0
- package/src/instinct-evolve.ts +44 -0
- package/src/instinct-export.ts +138 -0
- package/src/instinct-import.ts +260 -0
- package/src/instinct-injector.ts +128 -0
- package/src/instinct-loader.ts +146 -0
- package/src/instinct-parser.ts +171 -0
- package/src/instinct-projects.ts +119 -0
- package/src/instinct-promote.ts +231 -0
- package/src/instinct-status.ts +135 -0
- package/src/instinct-store.ts +149 -0
- package/src/instinct-tools.ts +340 -0
- package/src/observations.ts +82 -0
- package/src/observer-guard.ts +14 -0
- package/src/project.ts +70 -0
- package/src/prompt-observer.ts +92 -0
- package/src/prompts/analyzer-user.ts +156 -0
- package/src/prompts/evolve-prompt.ts +71 -0
- package/src/scrubber.ts +42 -0
- package/src/storage.ts +91 -0
- package/src/tool-observer.ts +114 -0
- package/src/types.ts +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matt Devy
|
|
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,326 @@
|
|
|
1
|
+
# pi-continuous-learning
|
|
2
|
+
|
|
3
|
+
A [Pi](https://github.com/nicholasgasior/pi-coding-agent) extension that observes your coding sessions and distills patterns into reusable "instincts" - atomic learned behaviors with confidence scoring, project scoping, and closed-loop feedback validation.
|
|
4
|
+
|
|
5
|
+
Inspired by [everything-claude-code/continuous-learning-v2](https://github.com/nicholasb/everything-claude-code), reimplemented as a native Pi extension in TypeScript.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Pi Session (extension) Background analyzer (standalone)
|
|
11
|
+
────────────────────── ──────────────────────────────────
|
|
12
|
+
Extension events Runs on a schedule (cron/launchd)
|
|
13
|
+
│ │
|
|
14
|
+
v v
|
|
15
|
+
Observation Collector Reads observations.jsonl per project
|
|
16
|
+
│ writes observations.jsonl │
|
|
17
|
+
v v
|
|
18
|
+
System Prompt Injection Haiku LLM analyzes patterns,
|
|
19
|
+
│ injects high-confidence instincts creates/updates instinct files
|
|
20
|
+
v │
|
|
21
|
+
Feedback Loop Instinct Files (.md with YAML frontmatter)
|
|
22
|
+
│ records which instincts were active
|
|
23
|
+
v
|
|
24
|
+
Confirms, contradicts, or ignores injected instincts
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**The key idea:** the extension watches what you do, learns patterns, injects relevant instincts into future sessions, then validates whether those instincts actually helped — adjusting confidence based on real outcomes rather than observation count alone.
|
|
28
|
+
|
|
29
|
+
The analyzer runs as a **separate background process** (not inside your Pi session), so it never causes lag or interference. It processes all your projects in a single pass.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pi install npm:pi-continuous-learning
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This installs the extension globally and makes the `pi-cl-analyze` CLI available on your PATH.
|
|
38
|
+
|
|
39
|
+
### Requirements
|
|
40
|
+
|
|
41
|
+
- [Pi](https://github.com/nicholasgasior/pi-coding-agent) >= 0.62.0
|
|
42
|
+
- An active Claude subscription (the analyzer uses Haiku via your existing Pi credentials — no separate API key needed)
|
|
43
|
+
- Node.js >= 18
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
Once installed, the extension runs automatically in your Pi sessions — observing events and injecting instincts. No configuration required for the extension itself.
|
|
48
|
+
|
|
49
|
+
To analyze observations and create/update instincts, you need to run the analyzer separately (see [Background Analyzer](#background-analyzer) below).
|
|
50
|
+
|
|
51
|
+
### Slash Commands
|
|
52
|
+
|
|
53
|
+
| Command | Description |
|
|
54
|
+
|---------|-------------|
|
|
55
|
+
| `/instinct-status` | Show all instincts grouped by domain with confidence scores and feedback stats |
|
|
56
|
+
| `/instinct-evolve` | LLM-powered analysis of instincts: suggests merges, promotions, and cleanup |
|
|
57
|
+
| `/instinct-export` | Export instincts to a JSON file (filterable by scope/domain) |
|
|
58
|
+
| `/instinct-import <path>` | Import instincts from a JSON file |
|
|
59
|
+
| `/instinct-promote [id]` | Promote project instincts to global scope |
|
|
60
|
+
| `/instinct-projects` | List all known projects and their instinct counts |
|
|
61
|
+
|
|
62
|
+
### LLM Tools
|
|
63
|
+
|
|
64
|
+
The extension registers tools that the LLM can use during conversation:
|
|
65
|
+
|
|
66
|
+
| Tool | Description |
|
|
67
|
+
|------|-------------|
|
|
68
|
+
| `instinct_list` | List instincts with optional scope/domain filters |
|
|
69
|
+
| `instinct_read` | Read a specific instinct by ID |
|
|
70
|
+
| `instinct_write` | Create or update an instinct |
|
|
71
|
+
| `instinct_delete` | Remove an instinct by ID |
|
|
72
|
+
| `instinct_merge` | Merge multiple instincts into one |
|
|
73
|
+
|
|
74
|
+
You can ask Pi things like "show me my instincts", "merge these two instincts", or "delete low-confidence instincts" and it will use these tools.
|
|
75
|
+
|
|
76
|
+
## Background Analyzer
|
|
77
|
+
|
|
78
|
+
The analyzer is a standalone CLI that processes observations across all your projects and creates/updates instincts using Haiku. It runs outside of Pi sessions for efficiency — one process handles all projects, regardless of how many Pi sessions you have open.
|
|
79
|
+
|
|
80
|
+
### Running manually
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pi-cl-analyze
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The script:
|
|
87
|
+
1. Iterates all projects in `~/.pi/continuous-learning/projects.json`
|
|
88
|
+
2. Skips projects with no new observations since last analysis
|
|
89
|
+
3. Skips projects with fewer than 20 observations (configurable)
|
|
90
|
+
4. For eligible projects: runs confidence decay, then uses Haiku to analyze patterns and write instinct files
|
|
91
|
+
5. Records a cursor so only new observations are processed on subsequent runs
|
|
92
|
+
|
|
93
|
+
**Safety features:**
|
|
94
|
+
- **Lockfile guard:** Only one instance can run at a time. Subsequent invocations exit immediately with code 0.
|
|
95
|
+
- **Global timeout:** The process exits after 5 minutes regardless of progress.
|
|
96
|
+
- **Stale lock detection:** If a previous run crashed, the lockfile is automatically cleaned up after 10 minutes or if the owning process is no longer alive.
|
|
97
|
+
|
|
98
|
+
### Setting up a schedule (macOS)
|
|
99
|
+
|
|
100
|
+
The recommended way to run the analyzer on a recurring schedule on macOS is with `launchd`, which persists across reboots and handles log rotation.
|
|
101
|
+
|
|
102
|
+
#### 1. Find the binary path
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
which pi-cl-analyze
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This should print something like `/opt/homebrew/bin/pi-cl-analyze`. Use this path in the plist below.
|
|
109
|
+
|
|
110
|
+
#### 2. Create the plist file
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
cat > ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist << EOF
|
|
114
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
115
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
116
|
+
<plist version="1.0">
|
|
117
|
+
<dict>
|
|
118
|
+
<key>Label</key>
|
|
119
|
+
<string>com.pi-continuous-learning.analyze</string>
|
|
120
|
+
<key>ProgramArguments</key>
|
|
121
|
+
<array>
|
|
122
|
+
<string>$(which pi-cl-analyze)</string>
|
|
123
|
+
</array>
|
|
124
|
+
<key>StartInterval</key>
|
|
125
|
+
<integer>300</integer>
|
|
126
|
+
<key>StandardOutPath</key>
|
|
127
|
+
<string>/tmp/pi-cl-analyze.log</string>
|
|
128
|
+
<key>StandardErrorPath</key>
|
|
129
|
+
<string>/tmp/pi-cl-analyze.log</string>
|
|
130
|
+
<key>EnvironmentVariables</key>
|
|
131
|
+
<dict>
|
|
132
|
+
<key>PATH</key>
|
|
133
|
+
<string>$(echo $PATH)</string>
|
|
134
|
+
</dict>
|
|
135
|
+
</dict>
|
|
136
|
+
</plist>
|
|
137
|
+
EOF
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
> **Note:** The `$(which pi-cl-analyze)` and `$(echo $PATH)` substitutions are evaluated when you run the `cat` command, so the plist will contain the resolved absolute paths from your current shell.
|
|
141
|
+
|
|
142
|
+
#### 3. Load the schedule
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
launchctl load ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The analyzer will now run every 5 minutes (300 seconds) in the background, starting on login. It's safe for overlapping triggers — the lockfile guard ensures only one instance runs.
|
|
149
|
+
|
|
150
|
+
#### 4. Verify it's running
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Check if the job is loaded
|
|
154
|
+
launchctl list | grep pi-continuous-learning
|
|
155
|
+
|
|
156
|
+
# View recent output
|
|
157
|
+
tail -20 /tmp/pi-cl-analyze.log
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Disabling the schedule
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Stop and unload (persists across reboots — the job will not restart)
|
|
164
|
+
launchctl unload ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
|
|
165
|
+
|
|
166
|
+
# Optionally remove the plist file entirely
|
|
167
|
+
rm ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### Temporarily pausing
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Disable (keeps the plist but prevents it from running)
|
|
174
|
+
launchctl unload ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
|
|
175
|
+
|
|
176
|
+
# Re-enable later
|
|
177
|
+
launchctl load ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Setting up a schedule (Linux/other)
|
|
181
|
+
|
|
182
|
+
Use cron:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Edit crontab
|
|
186
|
+
crontab -e
|
|
187
|
+
|
|
188
|
+
# Add this line (runs every 5 minutes):
|
|
189
|
+
*/5 * * * * pi-cl-analyze >> /tmp/pi-cl-analyze.log 2>&1
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
To disable, remove the line from `crontab -e`.
|
|
193
|
+
|
|
194
|
+
## Example instinct file
|
|
195
|
+
|
|
196
|
+
Instincts are stored as Markdown files with YAML frontmatter:
|
|
197
|
+
|
|
198
|
+
```yaml
|
|
199
|
+
---
|
|
200
|
+
id: grep-before-edit
|
|
201
|
+
title: Grep Before Edit
|
|
202
|
+
trigger: "when modifying code files"
|
|
203
|
+
confidence: 0.7
|
|
204
|
+
domain: "workflow"
|
|
205
|
+
source: "personal"
|
|
206
|
+
scope: project
|
|
207
|
+
project_id: "a1b2c3d4e5f6"
|
|
208
|
+
project_name: "my-project"
|
|
209
|
+
observation_count: 8
|
|
210
|
+
confirmed_count: 5
|
|
211
|
+
contradicted_count: 1
|
|
212
|
+
inactive_count: 12
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
Always search with grep to find relevant context before editing files.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Confidence Scoring
|
|
219
|
+
|
|
220
|
+
Confidence comes from two sources:
|
|
221
|
+
|
|
222
|
+
**Discovery** (initial, based on observation count):
|
|
223
|
+
- 1-2 observations: 0.3 (tentative)
|
|
224
|
+
- 3-5: 0.5 (moderate)
|
|
225
|
+
- 6-10: 0.7 (strong)
|
|
226
|
+
- 11+: 0.85 (very strong)
|
|
227
|
+
|
|
228
|
+
**Feedback** (ongoing, based on real outcomes):
|
|
229
|
+
- Confirmed (behavior aligned with instinct): +0.05
|
|
230
|
+
- Contradicted (behavior went against instinct): -0.15
|
|
231
|
+
- Inactive (instinct irrelevant to the turn): no change
|
|
232
|
+
- Passive decay: -0.02 per week without observations
|
|
233
|
+
- Range: 0.1 min, 0.9 max. Below 0.1 = flagged for removal.
|
|
234
|
+
|
|
235
|
+
This means an instinct observed 20 times but consistently contradicted in practice will lose confidence. Frequency alone doesn't equal correctness.
|
|
236
|
+
|
|
237
|
+
## Updating
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pi install npm:pi-continuous-learning
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Your observations, instincts, and configuration are stored separately in `~/.pi/continuous-learning/` and are preserved across updates.
|
|
244
|
+
|
|
245
|
+
If you have a launchd schedule set up, no changes needed — the plist points to the binary which npm updates in place.
|
|
246
|
+
|
|
247
|
+
## Configuration
|
|
248
|
+
|
|
249
|
+
Optional. Defaults work out of the box. Override at `~/.pi/continuous-learning/config.json`:
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"run_interval_minutes": 5,
|
|
254
|
+
"min_observations_to_analyze": 20,
|
|
255
|
+
"min_confidence": 0.5,
|
|
256
|
+
"max_instincts": 20,
|
|
257
|
+
"max_injection_chars": 4000,
|
|
258
|
+
"model": "claude-haiku-4-5",
|
|
259
|
+
"timeout_seconds": 120,
|
|
260
|
+
"active_hours_start": 8,
|
|
261
|
+
"active_hours_end": 23,
|
|
262
|
+
"max_idle_seconds": 1800
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Only include the fields you want to change — missing fields use the defaults above.
|
|
267
|
+
|
|
268
|
+
| Field | Default | Description |
|
|
269
|
+
|-------|---------|-------------|
|
|
270
|
+
| `min_observations_to_analyze` | 20 | Minimum observations before analysis triggers |
|
|
271
|
+
| `min_confidence` | 0.5 | Instincts below this are not injected into prompts |
|
|
272
|
+
| `max_instincts` | 20 | Maximum instincts injected per turn |
|
|
273
|
+
| `max_injection_chars` | 4000 | Character budget for the injection block (~1000 tokens) |
|
|
274
|
+
| `model` | `claude-haiku-4-5` | Model for the background analyzer |
|
|
275
|
+
| `timeout_seconds` | 120 | Per-project timeout for the analyzer LLM session |
|
|
276
|
+
|
|
277
|
+
## Storage
|
|
278
|
+
|
|
279
|
+
All data stays local on your machine:
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
~/.pi/continuous-learning/
|
|
283
|
+
config.json # Optional overrides
|
|
284
|
+
projects.json # Project registry
|
|
285
|
+
analyze.lock # Lockfile (present only while analyzer runs)
|
|
286
|
+
instincts/personal/ # Global instincts
|
|
287
|
+
projects/<hash>/
|
|
288
|
+
project.json # Project metadata + analysis cursor
|
|
289
|
+
observations.jsonl # Current observations
|
|
290
|
+
observations.archive/ # Archived (auto-purged after 30 days)
|
|
291
|
+
instincts/personal/ # Project-scoped instincts
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Privacy & Security
|
|
295
|
+
|
|
296
|
+
- All data stays on your machine — no external telemetry
|
|
297
|
+
- Secrets (API keys, tokens, passwords) are scrubbed from observations before writing to disk
|
|
298
|
+
- Only instincts (patterns) can be exported — never raw observations
|
|
299
|
+
- The analyzer reuses your existing Pi/Claude subscription credentials
|
|
300
|
+
- No separate API key required
|
|
301
|
+
|
|
302
|
+
## Development
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Install dependencies
|
|
306
|
+
npm install
|
|
307
|
+
|
|
308
|
+
# Run tests
|
|
309
|
+
npm test
|
|
310
|
+
|
|
311
|
+
# Lint
|
|
312
|
+
npm run lint
|
|
313
|
+
|
|
314
|
+
# Type check
|
|
315
|
+
npm run typecheck
|
|
316
|
+
|
|
317
|
+
# Build (compiles to dist/)
|
|
318
|
+
npm run build
|
|
319
|
+
|
|
320
|
+
# All checks
|
|
321
|
+
npm run check
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-instincts.d.ts","sourceRoot":"","sources":["../src/active-instincts.ts"],"names":[],"mappings":"AAEA,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAEpD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAE7D;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
let activeInstincts = [];
|
|
2
|
+
export function getCurrentActiveInstincts() {
|
|
3
|
+
return [...activeInstincts];
|
|
4
|
+
}
|
|
5
|
+
export function setCurrentActiveInstincts(ids) {
|
|
6
|
+
activeInstincts = [...ids];
|
|
7
|
+
}
|
|
8
|
+
export function clearActiveInstincts() {
|
|
9
|
+
activeInstincts = [];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=active-instincts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-instincts.js","sourceRoot":"","sources":["../src/active-instincts.ts"],"names":[],"mappings":"AAAA,IAAI,eAAe,GAAa,EAAE,CAAC;AAEnC,MAAM,UAAU,yBAAyB;IACvC,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,GAAa;IACrD,eAAe,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,eAAe,GAAG,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for reading AGENTS.md files.
|
|
3
|
+
* Provides a safe wrapper around filesystem access that returns null on any failure.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Reads an AGENTS.md file and returns its content.
|
|
7
|
+
* Returns null if the file does not exist or cannot be read.
|
|
8
|
+
*
|
|
9
|
+
* @param filePath - Absolute path to the AGENTS.md file
|
|
10
|
+
*/
|
|
11
|
+
export declare function readAgentsMd(filePath: string): string | null;
|
|
12
|
+
//# sourceMappingURL=agents-md.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.d.ts","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS5D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility for reading AGENTS.md files.
|
|
3
|
+
* Provides a safe wrapper around filesystem access that returns null on any failure.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
+
/**
|
|
7
|
+
* Reads an AGENTS.md file and returns its content.
|
|
8
|
+
* Returns null if the file does not exist or cannot be read.
|
|
9
|
+
*
|
|
10
|
+
* @param filePath - Absolute path to the AGENTS.md file
|
|
11
|
+
*/
|
|
12
|
+
export function readAgentsMd(filePath) {
|
|
13
|
+
if (!existsSync(filePath)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
return readFileSync(filePath, "utf-8");
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=agents-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-prompt.d.ts","sourceRoot":"","sources":["../../src/cli/analyze-prompt.ts"],"names":[],"mappings":"AAAA,wBAAgB,yBAAyB,IAAI,MAAM,CAsElD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export function buildAnalyzerSystemPrompt() {
|
|
2
|
+
return `You are a coding behavior analyst. Your job is to read session observations
|
|
3
|
+
and produce or update instinct files that capture reusable coding patterns.
|
|
4
|
+
|
|
5
|
+
Use the instinct_read tool to examine existing instincts and the instinct_write tool
|
|
6
|
+
to create or update instincts based on patterns you discover.
|
|
7
|
+
|
|
8
|
+
## Pattern Detection Heuristics
|
|
9
|
+
|
|
10
|
+
Analyze observations for these categories:
|
|
11
|
+
|
|
12
|
+
### User Corrections
|
|
13
|
+
- User rephrases a request after an agent response
|
|
14
|
+
- User explicitly rejects an approach
|
|
15
|
+
- Trigger: the corrected behavior; Action: the preferred approach
|
|
16
|
+
|
|
17
|
+
### Error Resolutions
|
|
18
|
+
- Tool call returns is_error: true followed by a successful retry
|
|
19
|
+
- Trigger: the error condition; Action: the proven resolution
|
|
20
|
+
|
|
21
|
+
### Repeated Workflows
|
|
22
|
+
- Same sequence of tool calls appears 3+ times
|
|
23
|
+
- Trigger: the workflow start condition; Action: the efficient path
|
|
24
|
+
|
|
25
|
+
### Tool Preferences
|
|
26
|
+
- Agent consistently uses one tool over alternatives
|
|
27
|
+
- Trigger: the task type; Action: the preferred tool and parameters
|
|
28
|
+
|
|
29
|
+
### Anti-Patterns
|
|
30
|
+
- Actions that consistently lead to errors or user corrections
|
|
31
|
+
- Trigger: the bad pattern situation; Action: what to do instead
|
|
32
|
+
|
|
33
|
+
## Feedback Analysis
|
|
34
|
+
|
|
35
|
+
Each observation may include an active_instincts field listing instinct IDs
|
|
36
|
+
that were injected into the agent's system prompt before that turn.
|
|
37
|
+
|
|
38
|
+
Use this to update existing instinct confidence scores:
|
|
39
|
+
- Confirmed (+0.05): instinct was active and agent followed the guidance without correction
|
|
40
|
+
- Contradicted (-0.15): instinct was active but user corrected the agent
|
|
41
|
+
- Inactive (no change): instinct was injected but trigger never arose
|
|
42
|
+
|
|
43
|
+
When updating, increment the corresponding count field and recalculate confidence.
|
|
44
|
+
|
|
45
|
+
## Confidence Scoring Rules
|
|
46
|
+
|
|
47
|
+
### Initial Confidence (new instincts)
|
|
48
|
+
- 1-2 observations -> 0.3
|
|
49
|
+
- 3-5 observations -> 0.5
|
|
50
|
+
- 6-10 observations -> 0.7
|
|
51
|
+
- 11+ observations -> 0.85
|
|
52
|
+
|
|
53
|
+
### Clamping
|
|
54
|
+
- Always clamp to [0.1, 0.9]
|
|
55
|
+
|
|
56
|
+
## Scope Decision Guide
|
|
57
|
+
|
|
58
|
+
Use project scope when the pattern is specific to this project's tech stack or conventions.
|
|
59
|
+
Use global scope when the pattern applies universally to any coding session.
|
|
60
|
+
When in doubt, prefer project scope.
|
|
61
|
+
|
|
62
|
+
## Conservativeness Rules
|
|
63
|
+
|
|
64
|
+
1. Only create a new instinct with 3+ clear independent observations supporting the pattern.
|
|
65
|
+
2. No code snippets in the action field - plain language only.
|
|
66
|
+
3. Each instinct must have one well-defined trigger.
|
|
67
|
+
4. New instincts from observation data alone are capped at 0.85 confidence.
|
|
68
|
+
5. Before creating, use instinct_list to check for duplicates. Update existing instincts instead.
|
|
69
|
+
6. Write actions as clear instructions starting with a verb.
|
|
70
|
+
7. Be skeptical of outliers - patterns seen only in unusual circumstances should not become instincts.`;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=analyze-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-prompt.js","sourceRoot":"","sources":["../../src/cli/analyze-prompt.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,yBAAyB;IACvC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uGAoE8F,CAAC;AACxG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/cli/analyze.ts"],"names":[],"mappings":""}
|