Skip to content
4 changes: 3 additions & 1 deletion INSTALL-LATEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ A bare "yes" / "ok" means **Use this version** β€” default to proceeding.
## Step 4 β€” set up memU

You now have the latest binaries. Identify **which agent you are** and use its
binary β€” memU has seven host adapters:
binary β€” memU has nine host adapters:

| You are | Your binary |
| --- | --- |
Expand All @@ -113,6 +113,8 @@ binary β€” memU has seven host adapters:
| OpenClaw | `memu-openclaw` |
| Hermes | `memu-hermes` |
| WorkBuddy | `memu-workbuddy` |
| Cola | `memu-cola` |
| pi | `memu-pi` |
| anything else | `memu-agent` β€” run `memu-agent detect` if unsure |

Then print your host's packaged guide and follow it to the letter:
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ memU is a lightweight, agent-driven memory system that gives users a shared LLM

## Quick start

memU works with Codex, Claude Code, Cursor, OpenClaw, Hermes, WorkBuddy, Cola, and more. See [Host adapters](#host-adapters-memory-for-desktop-coding-agents).
memU works with Codex, Claude Code, Cursor, OpenClaw, Hermes, WorkBuddy, Cola, pi, and more. See [Host adapters](#host-adapters-memory-for-desktop-coding-agents).

**Cross-device Β· Free Β· Unlimited Β· [View online](https://memu.so)**

Expand Down Expand Up @@ -127,6 +127,7 @@ memU runs as a sidecar to a desktop agent, one binary per host. Each binds two s
| Hermes Agent | `memu-hermes` | `~/.hermes/state.db` (SQLite, read-only) | `~/.hermes/SOUL.md` |
| WorkBuddy | `memu-workbuddy` | `~/.workbuddy/projects/<project>/<session>.jsonl` | `~/.workbuddy/SOUL.md` |
| Cola | `memu-cola` | `~/.cola/sessions/<scope>/<session>.jsonl` | `~/.cola/memory-bank/MEMORY.md` |
| pi | `memu-pi` | `~/.pi/agent/sessions/<encoded-cwd>/<session>.jsonl` | `~/.pi/agent/AGENTS.md` |
| **any other agent** | `memu-agent` | found by `memu-agent detect` (JSONL dialect sniffed) | found by `detect` (AGENTS.md / CLAUDE.md / SOUL.md / …) |

For agents without a dedicated binary, `memu-agent detect` probes the machine and reports per agent whether **memorization** works (a recognizable session log exists) and whether **retrieval** works (an instruction file exists to patch) β€” then the same verbs run against what it found.
Expand All @@ -149,7 +150,7 @@ Once installed, your agent retrieves relevant memory automatically before answer

```bash
memu-codex retrieve "What should I remember about this project?"
# or: memu-claude-code / memu-cursor / memu-openclaw / memu-hermes / memu-workbuddy / memu-agent
# or: memu-claude-code / memu-cursor / memu-openclaw / memu-hermes / memu-workbuddy / memu-cola / memu-pi / memu-agent
```

Install or invoke the CLI directly:
Expand Down
1 change: 1 addition & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ executing this skill):
| Hermes Agent | `memu-hermes` |
| WorkBuddy | `memu-workbuddy` |
| Cola | `memu-cola` |
| pi | `memu-pi` |
| anything else | `memu-agent` |

Unsure, or not in the table? You are `memu-agent`. Run:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ memu-openclaw = "memu.hosts.openclaw.cli:main"
memu-hermes = "memu.hosts.hermes.cli:main"
memu-workbuddy = "memu.hosts.workbuddy.cli:main"
memu-cola = "memu.hosts.cola.cli:main"
memu-pi = "memu.hosts.pi.cli:main"
# The generic adapter: any agent without a dedicated binary. `memu-agent
# detect` finds the session log and instruction file, then reports which of
# the two seams (memorization / retrieval) work for that agent.
Expand Down
1 change: 1 addition & 0 deletions src/memu/hosts/generic/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"""Instruction-file names the ecosystem's agents load into every session."""

DEDICATED = {
".pi": "memu-pi",
".codex": "memu-codex",
".claude": "memu-claude-code",
".cursor": "memu-cursor",
Expand Down
80 changes: 80 additions & 0 deletions src/memu/hosts/pi/BRIDGING_TASK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
name: {{task_doc_name}}
description: Register a scheduled pi run that bridges recent sessions into memU.
---

# Create the memU bridging task (pi)

## Task identity

- Current task name: `{{task_name}}`
- Former task names: {{former_task_names}}
- Names recognized during migration and removal: {{all_task_names}}

The task runs pi headlessly and defaults to hourly at minute 0. Reuse an
existing cadence unless the user requested a change.

## macOS and Linux

Write the following line verbatim to
`~/.memu/hosts/pi/bridge-prompt.txt`:

```text
Run the memU bridging pipeline. Do the four steps strictly in order; do not skip a step even if the previous one looks like it produced nothing. 1. LEFTOVERS. If ~/.memu/hosts/pi/jobs/ already contains job files, they are unfinished work from an earlier run (a crash, or the install itself) β€” process them exactly as step 3 describes, then run: memu-pi commit β€” and only then continue. 2. PREPARE. Run this exact command with bash: memu-pi prepare β€” it regenerates ~/.memu/hosts/pi/jobs/. If the command exits non-zero, stop and report the error. 3. SELF-EVOLVE. List ~/.memu/hosts/pi/jobs/*.txt and process them in ascending numeric order (1.txt, then 2.txt, …). The count changes every run β€” always glob and sort. If there are no job files, skip to step 4. For each job file: read it and follow its instructions to the letter. Each job is self-contained and already carries the concrete paths it needs. Emitting no files for a job is a valid outcome; do not invent content. 4. COMMIT. Run this exact command with bash: memu-pi commit β€” it commits whatever the jobs created or changed. If it exits non-zero, report the error. ON FAILURE. If step 2 or step 4 exited non-zero, run this once before you stop: memu-pi report error --stage remember --detail "<a full account of what went wrong>" β€” that detail is all a memU engineer gets to work out what is broken on this machine, so be generous: which step, what you ran, what happened instead, what you already tried, and what you think the cause is. Write it as prose for a human, not as a transcript β€” do not paste the traceback or raw command output, which the CLI already reports on its own, and keep credentials, absolute paths, and memory or transcript text out of it. Ignore any failure of that command; it is never part of the run. Finish with a one-line summary: how many jobs ran (leftovers included) and what was committed.
```

Write `~/.memu/hosts/pi/bridge.sh` and make it executable:

```sh
#!/bin/sh
DIR="$HOME/.memu/hosts/pi"
LOCK="$DIR/.bridge.lock"
if ! mkdir "$LOCK" 2>/dev/null; then
if [ -n "$(find "$LOCK" -maxdepth 0 -mmin +180 2>/dev/null)" ]; then
rmdir "$LOCK" 2>/dev/null
mkdir "$LOCK" 2>/dev/null || exit 0
else
exit 0
fi
fi
trap 'rmdir "$LOCK" 2>/dev/null' EXIT INT TERM
export MEMU_BRIDGING_RUN=1
pi -p "$(cat "$DIR/bridge-prompt.txt")" >> "$DIR/bridge.log" 2>&1
```

Add the directories containing `pi` and `memu-pi` to a crontab `PATH` line,
then register the short entry below. Never inline the long prompt in crontab.

```cron
PATH=<dirname-of-memu-pi>:<dirname-of-pi>:/usr/local/bin:/usr/bin:/bin
```

```cron
0 * * * * $HOME/.memu/hosts/pi/bridge.sh # {{task_name}}
```

Use launchd only if the user explicitly requests it; use `{{task_name}}` as its
label and invoke the same wrapper.

## Windows

Use the existing Task Scheduler helper, which writes the prompt and a
PowerShell wrapper to disk and registers a windowless task:

```powershell
memu-pi schedule install
memu-pi schedule verify
memu-pi schedule status
```

The helper resolves `pi` and registers `{{task_name}}`. `--interval <minutes>`
changes the default 60-minute cadence. `schedule verify` checks registration
only; it does not run the S4U task and is not end-to-end proof.

## Verify

Confirm the task is registered, then trigger one real OS run. Inspect
filesystem evidence: a new pi session appears, `bridge.log` grows, and the
session manifest or job timestamps advance. Do not rely only on the agent's
summary. The scheduled pi tool process exports `PI_SESSION_ID`, so `prepare`
records that run as bridge-owned and does not mine it later.
132 changes: 132 additions & 0 deletions src/memu/hosts/pi/INSTALL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Install memU for pi

## Task identity

- Current task name: `{{task_name}}`
- Former task names: {{former_task_names}}
- Names recognized during migration and removal: {{all_task_names}}

> **Audience: the agent.** Work top to bottom. Do not continue past a failing
> verify gate. Finish or abandon the run by reporting the outcome at the end.

Installing memU for pi has three parts: configure the shared memory backend,
schedule pi to bridge new sessions, and add the retrieval skill to pi's global
instructions.

## Part 1 β€” Install and configure memU

```sh
pip install --upgrade memu-cli
memu-pi --help
```

`--upgrade` matters: an existing older package otherwise stays installed. If
`memu-pi` is missing, the installed package predates this adapter or its scripts
directory is not on `PATH`.

Create the shared memU configuration. If `SKILL.md` already ran `init`, reusing
the existing mode is correct and re-running is harmless:

```sh
memu-pi init --cloud-api-key <the user's memU key>
```

Use bare `memu-pi init` for local memory. Never edit `~/.memu/config.env` by
hand. Inspect it with `memu-pi config show`; reuse an existing backend from
another host. Otherwise configure exactly one:

```sh
memu-pi config --cloud --cloud-api-key <memu-api-key>
memu-pi config --local --db /absolute/path/memu.sqlite3 --embed-provider openai --embed-api-key <key>
```

Give `--db` an absolute path. Shell-only environment variables do not reach a
scheduled run.

### Verify Part 1

```sh
memu-pi doctor
```

The command must exit cleanly. Zero retrieval hits is normal for a new store.

## Part 2 β€” Register the record bridge

Pi stores v3 JSONL sessions below `~/.pi/agent/sessions`. The adapter keeps
user and assistant text, routes tool calls and results to the full transcript,
and ignores session, compaction, model, and thinking metadata. The scheduled
bridge only supports this default layout.

**Refresh an existing bridging registration before continuing.** Check cron or
launchd for `hosts/pi/bridge\.sh|memU bridging pipeline`, or Task Scheduler for
`{{task_name}}`. Record its cadence and remove **only** that registration, then
verify it is gone. An absent registration is the normal first-install case.
Reuse the recorded cadence unless the user requested a change.

Follow the packaged scheduler procedure:

```sh
memu-pi docs task
```

### Verify Part 2

```sh
memu-pi prepare
```

It must report a session count. Zero is correct when no new turns exist.

## Part 3 β€” Install retrieval

Pi loads one global context file from its agent directory. Normally that is
`~/.pi/agent/AGENTS.md`; if `AGENTS.override.md` already exists there, it takes
precedence, so target that file instead.

Default installation:

```sh
memu-pi install-instruction
```

Custom or override installation:

```sh
memu-pi install-instruction --path <agent-dir>/AGENTS.override.md --skills-dir <agent-dir>/skills
```

The command creates `skills/memu-retrieve/SKILL.md` and adds one managed pointer
block to the selected global context file. Existing content is preserved;
re-running is idempotent.

### Verify Part 3

```sh
memu-pi retrieve "smoke test"
```

Confirm the managed block occurs once, the skill exists, and a fresh pi session
loads the selected context file. Empty result lists are valid.

## Report the outcome to memU

Every gate passed:

```sh
memu-pi report install
```

If the run stops early:

```sh
memu-pi report error --stage install --detail "<what failed, what was tried, and the likely cause>"
```

The report is best-effort. Do not include credentials, absolute paths, memory,
transcript text, or raw command output.

## Done

Tell the user which backend was selected, where the schedule was registered,
its cadence, and that retrieval takes effect in the next pi session.
31 changes: 31 additions & 0 deletions src/memu/hosts/pi/UNINSTALL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Uninstall memU for pi

## Task identity

- Current task name: `{{task_name}}`
- Former task names: {{former_task_names}}
- Names recognized during migration and removal: {{all_task_names}}

1. Remove only pi's memU schedule:
- cron/launchd: remove the entry invoking `~/.memu/hosts/pi/bridge.sh` or
labeled `{{task_name}}`;
- Windows: run `memu-pi schedule uninstall`, then confirm
`memu-pi schedule status` reports not registered.
2. Run `memu-pi remove-instruction`. If installation used custom `--path` or
`--skills-dir`, pass the same values. This removes only memU's managed block
and `memu-retrieve` skill; user content remains.
3. Keep `~/.memu/config.env`, its memory store, and
`~/.memu/hosts/pi/.session_manifest.pi.json` unless the user explicitly asks
to erase memory. Remove the other files under `~/.memu/hosts/pi/`.
4. Before removing the package, report the uninstall:

```sh
memu-pi report uninstall
```

On failure, use `memu-pi report error --stage uninstall --detail "<what
failed, what was tried, and the likely cause>"`. Reports are best-effort and
must not contain credentials, absolute paths, command output, memory, or
transcript text.
5. Remove `memu-cli` only if no other host adapter uses it. The event spool and
shared memory configuration also stay while another host remains.
5 changes: 5 additions & 0 deletions src/memu/hosts/pi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""The pi host adapter β€” ``memu-pi``."""

from memu.hosts.pi.sessions import PiTranscriptSource

__all__ = ["PiTranscriptSource"]
35 changes: 35 additions & 0 deletions src/memu/hosts/pi/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""``memu-pi`` β€” memU's pi host adapter."""

from __future__ import annotations

import sys

from memu.hosts.host_cli import HostSpec, run
from memu.hosts.pi.sessions import AGENT_DIR, SESSION_DIR, PiTranscriptSource

HOST = "pi"
AGENTS_MD = f"{AGENT_DIR}/AGENTS.md"
SKILLS_DIR = f"{AGENT_DIR}/skills"

SPEC = HostSpec(
host=HOST,
display="pi",
package="memu.hosts.pi",
task_name="memu-bridging-pi",
source_factory=PiTranscriptSource,
session_dir=SESSION_DIR,
session_help="pi v3 JSONL session directory (one directory per encoded cwd)",
instruction_path=AGENTS_MD,
skills_dir=SKILLS_DIR,
schedule_backend="os",
schedule_command="pi -p {prompt}",
session_id_env="PI_SESSION_ID",
)


def main(argv: list[str] | None = None) -> int:
return run(SPEC, argv)


if __name__ == "__main__":
sys.exit(main())
Loading