@wierdbytes/pi-dream
Offline memory consolidation ("dreaming") for pi: distills past sessions into small, evidence-backed memory notes, sends every change to a GitHub pull request for review, injects the approved index into new sessions and adds memory search / read / inbox t
Package details
Install @wierdbytes/pi-dream from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@wierdbytes/pi-dream- Package
@wierdbytes/pi-dream- Version
0.2.0- Published
- Nov 9, 2026
- Downloads
- 366/mo · 366/wk
- Author
- wierdbytes
- License
- MIT
- Types
- extension
- Size
- 308.7 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@wierdbytes/pi-dream
Offline memory consolidation — "dreaming" — for the pi coding agent.
While you work, pi sessions pile up in ~/.pi/agent/sessions. Every so often pi-dream "falls asleep" in a background pi process, reads the new sessions, and distills what future sessions will need into a few small, evidence-backed memory notes. Every change goes to a pull request in your private memory repository; only what you merge is loaded into new sessions — as a small index, within a token budget, frozen per session so the prompt cache keeps hitting.
Built after Anthropic's The components of agent memory and the evidence on what makes agent memory hurt: wrong or stale notes, full-text rewrites, bloated always-on context.
Install
pi install npm:@wierdbytes/pi-dream
Then, in pi:
/dream init
This creates ~/.pi/memory (a git repo), a private GitHub repository <you>/pi-memory as its origin (needs the gh CLI, logged in), a pi-dream label, and ~/.pi/agent/@wierdbytes/pi-dream/settings.json.
How a dream works
Digests. Every session (active branch) becomes a compact digest: user messages, assistant text, one line per tool call, tool-result heads, errors; no images, no thinking; credentials scrubbed. Digests are also the corpus for
memory_search.Cards (
anthropic/claude-sonnet-5-5). Each new or grown session gets a card: what happened, how it ended, the user's feedback (verbatim), candidate learnings — each citing digest entry ids.Curator (
anthropic/claude-opus-5-5, per project). Sees the current notes (global + project), the cards, history hits (older sessions that mention a candidate, to judge recurrence), other projects the evidence points to, inbox items, the project's AGENTS.md, and what you rejected before. Proposes operations:add,update(also moves a note to another scope),supersede,deprecate,confirm,skill,agents_md.Scope. A session belongs to the project it was about, not to the folder pi was started in: when pi runs in a workspace folder (
~/me/dev,~— a folder that contains other projects), the session goes to the project whose files it worked with most. Only real projects count (git repositories or folders with markers such as.pi,AGENTS.md,package.json);~/Downloadsor/tmpnever become one.globalis only for your general preferences and machine-wide setup; a topic used in several projects goes to each of them. The fact checker can move a note out of global, and code refuses global notes whose evidence comes from a single project without your own words.Fact check (
openai-codex/gpt-6.1-sol). Every cited entry is looked up in the raw session; operations citing entries that do not exist are dropped. An independent model checks each operation against those excerpts: supported, partial (with a fix), unsupported, contradicted, unsafe.Code applies what passed — item by item, never a full rewrite; near-duplicates merge into the existing note; superseded notes stay with
valid_until; credentials and prompt-injection patterns are refused.MEMORY.mdindexes are regenerated from note front matter within the token budgets.Pull request. Changes are committed on a
pi-dream/…branch with the dream's full report (reports/<run>.md: every change with its rationale, evidence and fact check, plus what the check rejected). The PR description is the review view of the whole PR: counts and what to check before merging (risky commands, failed AGENTS.md edits, over-budget indexes) on top, then one line per note grouped by project — marked when it loads into every session (always / on demand) — with the note text, rationale and sessions folded under it. While a PR is open, later dreams add commits to it, rebuild the description from the branch (so it shows what merging does, review comments and your edits included) and leave a short comment with what they changed.AGENTS.md / CLAUDE.md edits become pull requests in the project's own repository (from a temporary worktree, your working copy is never touched; public repos get no session details). One open proposal per repository: no new one is made while it awaits review.
Reviewing:
- Merge — the changes become memory.
- Edit notes in the PR — the next dream continues from your version.
- Comment on the PR — an instruction for the dream (edit, drop, move to another project);
/dream reviewapplies new comments right away without processing new sessions. - Close without merging — the notes count as rejected and are not proposed again without new evidence.
In a session
- A
<memory>section with the approved global index and the current project's index (built on the first turn, frozen for the session, replayed on resume). Nothing is injected while memory is empty. memory_search— notes and past-session digests (BM25, Russian + English).memory_read— a note (m-xxxxxx) with its evidence, or a past session entry (s:<session>#<entry>).memory_inbox— keep something for the next dream; it becomes memory only after review./remember <text>— the same, from you./memory— what this session got;/memory sync— pull merged memory now./dream— status;/dream run [--since <days>] [--max <sessions>],/dream review(apply new PR comments now),/dream dry(no push, report and worktree stay local),/dream index(rebuild digests),/dream log,/dream init.--no-memory— no injection and no memory tools for this run (PI_DREAM_DISABLE=1does the same).
When it dreams
pi is the scheduler: when a session starts and a dream is due — at least schedule.minHoursBetween hours (20) since the last one and schedule.minNewSessions (3) new sessions or inbox items — a detached headless pi process runs it:
pi -p --no-session --no-extensions -e <childExtensions…> -e runner.ts "/pi-dream-run …"
It survives the interactive pi exiting, holds a lock (one dream at a time across all pi processes; stale locks are taken over), and loads only the extensions listed in dream.childExtensions (default: @wierdbytes/pi-anthropic, so Claude Pro/Max OAuth behaves as in your sessions). Sessions written to in the last dream.minIdleMinutes (30) are left for the next dream.
Memory repository
~/.pi/memory/
scopes/global/{charter.md, MEMORY.md, notes/, skills/}
scopes/projects/<key>/{charter.md?, MEMORY.md, notes/, skills/, scope.json}
scopes/projects/_charter.md default purpose of project memory
reports/<run>.md
prompts/{cards,curator,review,verify}.md optional prompt overrides
.local/ gitignored: inbox, digests, cards, runs, logs, state
Projects are keyed by their origin remote (github.com/owner/repo) or by path; worktrees map to their main repository. charter.md says what a scope's memory is for — it steers the dream and is never injected.
Settings
~/.pi/agent/@wierdbytes/pi-dream/settings.json:
| Key | Default | |
|---|---|---|
memoryDir |
~/.pi/memory |
memory repository (PI_DREAM_DIR overrides) |
language |
Russian |
language of notes and reports |
inject |
true |
inject the approved index into sessions |
models.cards / analyze / verify |
Sonnet 5.5 low / Opus 5.5 high / GPT-6.1 sol medium | { "model": "provider/id", "thinking": "…" } |
schedule |
{ enabled: true, minHoursBetween: 20, minNewSessions: 3 } |
when a dream is due |
dream.firstRunLookbackDays |
14 |
how far back the first dream looks |
dream.maxSessionsPerRun |
60 |
the rest waits for the next dream |
dream.minIdleMinutes |
30 |
sessions written more recently are skipped |
dream.concurrency |
4 |
parallel card calls |
dream.maxRuntimeMinutes |
180 |
hard limit of one dream |
dream.childExtensions |
["npm:@wierdbytes/pi-anthropic"] |
extensions the dream process loads |
budgets.globalTokens / projectTokens |
1000 / 1500 |
index budgets |
github |
{ repo: "pi-memory", base: "main", label: "pi-dream" } |
|
agentsMd |
true |
propose AGENTS.md / CLAUDE.md changes |
Development
cd packages/dream && bun run test
pi -e ./index.ts # try in a session