
Security News
/Company News
Socket Is Sponsoring Composer and Packagist
Socket has joined the new Composer and Packagist sponsorship program as a launch sponsor, supporting the team that keeps PHP's package ecosystem secure.
pi-continuous-learning
Advanced tools
A Pi extension that observes coding sessions and distills patterns into reusable instincts.
A Pi 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.
Inspired by everything-claude-code/continuous-learning-v2, reimplemented as a native Pi extension in TypeScript.
Pi Session (extension) Background analyzer (standalone)
────────────────────── ──────────────────────────────────
Extension events Runs on a schedule (cron/launchd)
│ │
v v
Observation Collector Reads observations.jsonl per project
│ writes observations.jsonl │
v v
System Prompt Injection Haiku LLM analyzes patterns,
│ injects high-confidence instincts creates/updates instinct files
v │
Feedback Loop Instinct Files (.md with YAML frontmatter)
│ records which instincts were active
v
Confirms, contradicts, or ignores injected instincts
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.
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.
pi install npm:pi-continuous-learning
This installs the extension globally and makes the pi-cl-analyze CLI available on your PATH.
Once installed, the extension runs automatically in your Pi sessions — observing events and injecting instincts. No configuration required for the extension itself.
To analyze observations and create/update instincts, you need to run the analyzer separately (see Background Analyzer below).
| Command | Description |
|---|---|
/instinct-status | Show all instincts grouped by domain with confidence scores and feedback stats |
/instinct-evolve | LLM-powered analysis of instincts: suggests merges, promotions, and cleanup |
/instinct-export | Export instincts to a JSON file (filterable by scope/domain) |
/instinct-import <path> | Import instincts from a JSON file |
/instinct-promote [id] | Promote project instincts to global scope |
/instinct-graduate | Graduate mature instincts to AGENTS.md, skills, or commands |
/instinct-projects | List all known projects and their instinct counts |
The extension registers tools that the LLM can use during conversation:
| Tool | Description |
|---|---|
instinct_list | List instincts with optional scope/domain filters |
instinct_read | Read a specific instinct by ID |
instinct_write | Create or update an instinct |
instinct_delete | Remove an instinct by ID |
instinct_merge | Merge multiple instincts into one |
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.
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.
pi-cl-analyze
The script:
~/.pi/continuous-learning/projects.jsonSafety features:
The analyzer writes structured JSON logs to ~/.pi/continuous-learning/analyzer.log (configurable via log_path in config). Each run logs:
Each log line is a JSON object, making it easy to parse with jq:
# View recent run summaries
cat ~/.pi/continuous-learning/analyzer.log | jq 'select(.event == "run_complete")'
# Check total cost over time
cat ~/.pi/continuous-learning/analyzer.log | jq 'select(.event == "run_complete") | .total_cost_usd'
# See which projects were processed
cat ~/.pi/continuous-learning/analyzer.log | jq 'select(.event == "project_complete") | {project: .project_name, duration_s: (.duration_ms/1000), cost: .cost_usd}'
The log file auto-rotates at 10 MB (old content moved to analyzer.log.old). When the log file is not writable, output falls back to stderr.
The recommended way to run the analyzer on a recurring schedule on macOS is with launchd, which persists across reboots and handles log rotation.
which pi-cl-analyze
This should print something like /opt/homebrew/bin/pi-cl-analyze. Use this path in the plist below.
cat > ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.pi-continuous-learning.analyze</string>
<key>ProgramArguments</key>
<array>
<string>$(which pi-cl-analyze)</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
<key>StandardOutPath</key>
<string>/tmp/pi-cl-analyze-stdout.log</string>
<key>StandardErrorPath</key>
<string>/tmp/pi-cl-analyze-stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>$(echo $PATH)</string>
</dict>
</dict>
</plist>
EOF
Note: The
$(which pi-cl-analyze)and$(echo $PATH)substitutions are evaluated when you run thecatcommand, so the plist will contain the resolved absolute paths from your current shell.
launchctl load ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
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.
# Check if the job is loaded
launchctl list | grep pi-continuous-learning
# View recent log entries (structured JSON)
tail -5 ~/.pi/continuous-learning/analyzer.log | jq .
# View stderr output (fallback only)
tail -20 /tmp/pi-cl-analyze-stderr.log
# Stop and unload (persists across reboots — the job will not restart)
launchctl unload ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
# Optionally remove the plist file entirely
rm ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
# Disable (keeps the plist but prevents it from running)
launchctl unload ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
# Re-enable later
launchctl load ~/Library/LaunchAgents/com.pi-continuous-learning.analyze.plist
Use cron:
# Edit crontab
crontab -e
# Add this line (runs every 5 minutes):
*/5 * * * * pi-cl-analyze 2>> /tmp/pi-cl-analyze-stderr.log
To disable, remove the line from crontab -e.
Instincts are stored as Markdown files with YAML frontmatter:
---
id: grep-before-edit
title: Grep Before Edit
trigger: "when modifying code files"
confidence: 0.7
domain: "workflow"
source: "personal"
scope: project
project_id: "a1b2c3d4e5f6"
project_name: "my-project"
observation_count: 8
confirmed_count: 5
contradicted_count: 1
inactive_count: 12
---
Always search with grep to find relevant context before editing files.
Graduated instincts include additional fields:
---
id: grep-before-edit
# ...other fields...
graduated_to: agents-md
graduated_at: "2026-03-27T12:00:00.000Z"
---
Every instinct write (from the LLM tools or the background analyzer) is validated and deduplicated before being saved.
| Rule | Details |
|---|---|
| Non-empty fields | action and trigger cannot be undefined, null, "null", "none", or empty |
| Minimum length | Both fields must be >= 10 characters |
| Known domain | domain must be in the known set: git, testing, debugging, workflow, typescript, javascript, python, go, css, design, security, performance, documentation, react, node, database, api, devops, architecture, or other |
| Verb heuristic | action should start with an imperative verb - a warning is logged but the write is not rejected |
Before a new instinct is created, a Jaccard similarity check runs against all existing instincts. Tokenize trigger + action, compute |intersection| / |union|, and block the write if any existing instinct scores >= 0.6.
This prevents near-duplicate instincts from accumulating. When a similar instinct exists, the LLM is told to update the existing one instead.
The background analyzer is instructed to classify patterns before recording them:
The analyzer also checks AGENTS.md content before creating instincts - if a pattern is already covered by AGENTS.md, it is skipped.
Confidence comes from two sources:
Discovery (initial, based on observation count):
Feedback (ongoing, based on real outcomes):
This means an instinct observed 20 times but consistently contradicted in practice will lose confidence. Frequency alone doesn't equal correctness.
Instincts are designed to be short-lived - they should graduate into permanent knowledge within a few weeks. The graduation pipeline (/instinct-graduate) handles this lifecycle:
Observation -> Instinct (days) -> AGENTS.md / Skill / Command (1-2 weeks)
| Target | When | What happens |
|---|---|---|
| AGENTS.md | Single mature instinct | Appended as a guideline entry to your project or global AGENTS.md |
| Skill | 3+ related instincts in the same domain | Scaffolded into a SKILL.md file |
| Command | 3+ workflow instincts in the same domain | Scaffolded into a slash command specification |
An instinct qualifies for graduation when all of these are met:
Instincts that don't graduate within 28 days are subject to TTL enforcement:
Graduated instincts are tracked with graduated_to and graduated_at fields so they aren't left as duplicates of the knowledge they graduated into.
pi install npm:pi-continuous-learning
Your observations, instincts, and configuration are stored separately in ~/.pi/continuous-learning/ and are preserved across updates.
If you have a launchd schedule set up, no changes needed — the plist points to the binary which npm updates in place.
Optional. Defaults work out of the box. Override at ~/.pi/continuous-learning/config.json:
{
"run_interval_minutes": 5,
"min_observations_to_analyze": 20,
"min_confidence": 0.5,
"max_instincts": 20,
"max_injection_chars": 4000,
"model": "claude-haiku-4-5",
"timeout_seconds": 120,
"active_hours_start": 8,
"active_hours_end": 23,
"max_idle_seconds": 1800
}
Only include the fields you want to change — missing fields use the defaults above.
| Field | Default | Description |
|---|---|---|
run_interval_minutes | 5 | How often the analyzer is expected to run (informational, used for decay calculations) |
min_observations_to_analyze | 20 | Minimum observations before analysis triggers |
min_confidence | 0.5 | Instincts below this are not injected into prompts |
max_instincts | 20 | Maximum instincts injected per turn |
max_injection_chars | 4000 | Character budget for the injection block (~1000 tokens) |
model | claude-haiku-4-5 | Model for the background analyzer (lightweight models recommended to minimize cost) |
timeout_seconds | 120 | Per-project timeout for the analyzer LLM session |
active_hours_start | 8 | Hour (0-23) at which the active observation window starts |
active_hours_end | 23 | Hour (0-23) at which the active observation window ends |
max_idle_seconds | 1800 | Seconds of inactivity before a session is considered idle |
log_path | ~/.pi/continuous-learning/analyzer.log | Path to the analyzer log file |
All data stays local on your machine:
~/.pi/continuous-learning/
config.json # Optional overrides
projects.json # Project registry
analyze.lock # Lockfile (present only while analyzer runs)
instincts/personal/ # Global instincts
projects/<hash>/
project.json # Project metadata + analysis cursor
observations.jsonl # Current observations
observations.archive/ # Archived (auto-purged after 30 days)
instincts/personal/ # Project-scoped instincts
# Install dependencies
npm install
# Run tests
npm test
# Lint
npm run lint
# Type check
npm run typecheck
# Build (compiles to dist/)
npm run build
# All checks
npm run check
MIT
FAQs
A Pi extension that observes coding sessions and distills patterns into reusable instincts.
The npm package pi-continuous-learning receives a total of 98 weekly downloads. As such, pi-continuous-learning popularity was classified as not popular.
We found that pi-continuous-learning demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
/Company News
Socket has joined the new Composer and Packagist sponsorship program as a launch sponsor, supporting the team that keeps PHP's package ecosystem secure.

Research
/Security News
Benign-looking npm packages split malicious functionality across a dependency chain that deploys a cross-platform RAT targeting Alibaba developers.

Research
/Security News
Two Joyfill npm beta releases contain an import-time implant that uses blockchain transactions to retrieve a remote-access trojan.