Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ npm run test:smoke
## PR checklist

- [ ] No changes to unrelated files
- [ ] Native build still succeeds (`-Wall -Wextra -Wpedantic`)
- [ ] Native build still succeeds (`-Wall -Wextra -Wpedantic` on Unix, supported Windows compiler path still works)
- [ ] `npm run test:smoke` passes
- [ ] Docs updated
- [ ] Backward compatibility considered
Expand Down
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Durable memory for Pi agents, built for **low-overhead reliability**:
- **C core** (`native/pi-memory.c`) for speed + minimal runtime surface
- **TypeScript extension** (`extensions/pi-memory-compact.ts`) for Pi lifecycle automation
- **SQLite DB** (`~/.pi/memory/memory.db`) for single-file durability and simple ops
- **SQLite DB** (`~/.pi/memory/memory.db` on Unix, `%USERPROFILE%\\.pi\\memory\\memory.db` on Windows) for single-file durability and simple ops

Repository: https://github.com/SiliconState/Pi-Memory

Expand All @@ -18,7 +18,7 @@ Pi-Memory is intentionally small:
- no server process
- no external DB
- no runtime framework dependency for core memory engine
- one local DB: `~/.pi/memory/memory.db`
- one local DB in your user `.pi/memory` directory

That keeps startup fast, failure modes simple, and behavior predictable.

Expand All @@ -30,14 +30,14 @@ Pi-Memory is designed as a layered system where each layer has a different job:

| Layer | Responsibility | Location |
|---|---|---|
| **1. Core memory engine (C + SQLite)** | Stores structured memory: decisions, findings, lessons, entities, sessions, project state | `~/.pi/memory/pi-memory` + `~/.pi/memory/memory.db` |
| **1. Core memory engine (C + SQLite)** | Stores structured memory: decisions, findings, lessons, entities, sessions, project state | user `.pi/memory` dir (`pi-memory`/`pi-memory.exe` + `memory.db`) |
| **2. Pi lifecycle extension (TypeScript)** | Hooks into compaction/session events, syncs memory, ingests sessions, resumes intent | `extensions/pi-memory-compact.ts` (installed by Pi package) |
| **3. Project memory files (`MEMORY.md`)** | Human-readable, per-project snapshot used as context bridge across sessions | project root `MEMORY.md` with sync markers |

Check current DB coverage at any time:

```bash
~/.pi/memory/pi-memory projects
pi-memory projects
```

---
Expand Down Expand Up @@ -81,7 +81,7 @@ This installs all Pi components declared in `package.json`:
- prompts (`prompts/*.md`)
- native C binary compile via postinstall

### Alternative one-liner installer (curl)
### Alternative one-liner installer (Unix only)

```bash
curl -fsSL https://raw.githubusercontent.com/SiliconState/Pi-Memory/main/scripts/install.sh | bash
Expand All @@ -90,20 +90,23 @@ curl -fsSL https://raw.githubusercontent.com/SiliconState/Pi-Memory/main/scripts
Then verify:

```bash
~/.pi/memory/pi-memory --version
pi-memory --version
```

> SQLite is bundled — the only build prerequisite is a C compiler (`cc`/`gcc`/`clang`).
> If native compile is skipped during install, rerun the curl installer or follow manual compile troubleshooting in `docs/INSTALL.md`.
> SQLite is bundled — the only build prerequisite is a C compiler.
> - Unix: `cc` / `gcc` / `clang`
> - Windows: `clang`, `gcc`, or Visual Studio `cl`
>
> npm/bun publish is planned but not currently live. For now, use the git install (or curl wrapper) above.
> If native compile is skipped during install, follow the manual compile troubleshooting in `docs/INSTALL.md`.
>
> npm/bun publish is planned but not currently live. For now, use the git install above.

---

## Quick Start

```bash
BIN="${PI_MEMORY_BIN:-$HOME/.pi/memory/pi-memory}"
BIN="${PI_MEMORY_BIN:-pi-memory}"

# initialize MEMORY.md markers
"$BIN" init
Expand Down Expand Up @@ -140,8 +143,8 @@ Inside Pi, you can manually tune compaction behavior without changing code:
If you want this change recorded in project memory for teammates/future sessions:

```bash
~/.pi/memory/pi-memory state <project> --summary "Compaction threshold set to 75%"
~/.pi/memory/pi-memory sync MEMORY.md --project <project> --limit 15
pi-memory state <project> --summary "Compaction threshold set to 75%"
pi-memory sync MEMORY.md --project <project> --limit 15
```

---
Expand Down
3 changes: 2 additions & 1 deletion bin/pi-memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.resolve(__dirname, "..");
const setupScript = path.join(root, "scripts", "setup.mjs");

const binary = process.env.PI_MEMORY_BIN?.trim() || path.join(os.homedir(), ".pi", "memory", "pi-memory");
const defaultBinary = os.platform() === "win32" ? "pi-memory.exe" : "pi-memory";
const binary = process.env.PI_MEMORY_BIN?.trim() || path.join(os.homedir(), ".pi", "memory", defaultBinary);

if (!existsSync(binary)) {
const setup = spawnSync(process.execPath, [setupScript], { stdio: "inherit" });
Expand Down
4 changes: 3 additions & 1 deletion docs/AGENT-USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

This guide is for agent authors/operators using Pi-Memory in Pi workflows.

If `pi-memory` is not on PATH in your environment, call it explicitly as `~/.pi/memory/pi-memory`.
If `pi-memory` is not on PATH in your environment, call the installed binary directly:
- macOS / Linux: `~/.pi/memory/pi-memory`
- Windows: `%USERPROFILE%\\.pi\\memory\\pi-memory.exe`

## Core operating rules

Expand Down
5 changes: 3 additions & 2 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ The C binary is the source of truth for persistence.
SQLite database:

```text
~/.pi/memory/memory.db
~/.pi/memory/memory.db # macOS / Linux
%USERPROFILE%\\.pi\\memory\\memory.db # Windows
```

Primary tables:
Expand Down Expand Up @@ -69,7 +70,7 @@ The extension automates operational memory hygiene around compaction and shutdow

The packaged extension resolves pi-memory in this order:
1. `PI_MEMORY_BIN` env var
2. `~/.pi/memory/pi-memory`
2. default binary in the user `.pi/memory` dir (`pi-memory` on Unix, `pi-memory.exe` on Windows)
3. fallback command `pi-memory` in PATH

## MEMORY.md bridge layer
Expand Down
85 changes: 70 additions & 15 deletions docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,150 @@
## Platform support

- **macOS** and **Linux** are supported.
- **Windows** is not currently supported (no native build target).
- **Windows** is supported with a native Windows C compiler (`clang`, `gcc`, or `cl`).

## Prerequisites

- Pi installed (`pi` CLI)
- C compiler (`cc`/`clang`/`gcc`)
- C compiler
- macOS/Linux: `cc` / `clang` / `gcc`
- Windows: `clang`, `gcc`, or Visual Studio `cl`

> SQLite is bundled (amalgamation compiled directly into the binary). No system `libsqlite3-dev` or `sqlite3.h` needed.
> SQLite is bundled (amalgamation compiled directly into the binary). No system `libsqlite3-dev`, `sqlite3.h`, or external database server is required.

## Option A (recommended): single Pi command

```bash
pi install git:github.com/SiliconState/Pi-Memory
```

This installs package resources declared in `package.json` (`pi.extensions`, `pi.skills`, `pi.prompts`) and runs native build postinstall.
This installs package resources declared in `package.json` (`pi.extensions`, `pi.skills`, `pi.prompts`) and runs the native build in `postinstall`.

Verify:

### macOS / Linux
```bash
~/.pi/memory/pi-memory --version
```

## Option B: single curl command
### Windows (PowerShell)
```powershell
$env:USERPROFILE\.pi\memory\pi-memory.exe --version
```

## Option B: Unix convenience installer

```bash
curl -fsSL https://raw.githubusercontent.com/SiliconState/Pi-Memory/main/scripts/install.sh | bash
```

The installer script runs `pi install ...` and falls back to direct compile if needed.
The shell installer is **Unix-only**. On Windows, use Option A or the manual compile step below.

## npm/bun status

npm/bun publish is planned but not currently live.

Use Option A (`pi install git:...`) or Option B (curl installer) for now.
Use Option A (`pi install git:...`) for now.

## Native build output

Default binary location:

### macOS / Linux
```text
~/.pi/memory/pi-memory
~/.pi/memory/memory.db
```

Database:

### Windows
```text
~/.pi/memory/memory.db
%USERPROFILE%\.pi\memory\pi-memory.exe
%USERPROFILE%\.pi\memory\memory.db
```

Override binary path with:

### macOS / Linux
```bash
export PI_MEMORY_BIN=/custom/path/pi-memory
```

### Windows (PowerShell)
```powershell
$env:PI_MEMORY_BIN = 'C:\custom\path\pi-memory.exe'
```

## Troubleshooting

### `Failed to compile pi-memory`

Install build prerequisites and rerun the installer:
Install a basic C compiler and rerun:

```bash
pi install git:github.com/SiliconState/Pi-Memory
```

If needed, compile manually:
Or from the package directory:

```bash
npm run setup
```

### Manual compile — macOS / Linux

```bash
PKG="$HOME/.pi/agent/git/github.com/SiliconState/Pi-Memory"
[ -d "$PKG" ] || PKG="$HOME/.pi/git/github.com/SiliconState/Pi-Memory"
mkdir -p "$HOME/.pi/memory"
cc -Wall -Wextra -Wpedantic -O2 -std=c11 -o "$HOME/.pi/memory/pi-memory" \
"$PKG/native/pi-memory.c" "$PKG/native/sqlite3.c" -lpthread -ldl -lm
"$PKG/native/pi-memory.c" "$PKG/native/sqlite3.c" "$PKG/native/getopt_compat.c" -lpthread -ldl -lm
chmod +x "$HOME/.pi/memory/pi-memory"
```

### Manual compile — Windows (PowerShell + clang/gcc)

```powershell
$pkg = "$env:USERPROFILE\.pi\agent\git\github.com\SiliconState\Pi-Memory"
if (-not (Test-Path $pkg)) { $pkg = (Resolve-Path ".\Pi-Memory").Path }
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.pi\memory" | Out-Null
clang -D_CRT_SECURE_NO_WARNINGS -Wall -Wextra -Wpedantic -O2 -std=c11 `
-o "$env:USERPROFILE\.pi\memory\pi-memory.exe" `
"$pkg\native\pi-memory.c" "$pkg\native\sqlite3.c" "$pkg\native\getopt_compat.c"
```

### Manual compile — Windows (Developer PowerShell + MSVC `cl`)

```powershell
$pkg = "$env:USERPROFILE\.pi\agent\git\github.com\SiliconState\Pi-Memory"
if (-not (Test-Path $pkg)) { $pkg = (Resolve-Path ".\Pi-Memory").Path }
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.pi\memory" | Out-Null
cl /nologo /D_CRT_SECURE_NO_WARNINGS /O2 /W4 /EHsc `
/Fe:"$env:USERPROFILE\.pi\memory\pi-memory.exe" `
"$pkg\native\pi-memory.c" "$pkg\native\sqlite3.c" "$pkg\native\getopt_compat.c"
```

### Extension can’t find binary

Set explicit path:

#### macOS / Linux
```bash
export PI_MEMORY_BIN="$HOME/.pi/memory/pi-memory"
```

#### Windows (PowerShell)
```powershell
$env:PI_MEMORY_BIN = "$env:USERPROFILE\.pi\memory\pi-memory.exe"
```

### Check health quickly

#### macOS / Linux
```bash
~/.pi/memory/pi-memory --version
~/.pi/memory/pi-memory help
```

#### Windows (PowerShell)
```powershell
$env:USERPROFILE\.pi\memory\pi-memory.exe --version
$env:USERPROFILE\.pi\memory\pi-memory.exe help
```
18 changes: 17 additions & 1 deletion extensions/pi-memory-compact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import { complete, type Model } from "@mariozechner/pi-ai";
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { convertToLlm, serializeConversation } from "@mariozechner/pi-coding-agent";
import { existsSync, readFileSync } from "node:fs";
import os from "node:os";
import path from "node:path";

const DEFAULT_COMPACT_THRESHOLD = parseThresholdValue(process.env.PI_COMPACT_THRESHOLD, 0.6); // 60% default
Expand Down Expand Up @@ -74,6 +76,19 @@ function formatThresholdPercent(ratio: number): string {
}

function getProjectKey(cwd: string): string {
const pinned = process.env.PI_MEMORY_PROJECT?.trim();
if (pinned) return pinned;

try {
const memoryFile = path.join(cwd, "MEMORY.md");
if (existsSync(memoryFile)) {
const header = readFileSync(memoryFile, "utf8").match(/^#\s+Memory\s+[—-]\s+(.+)$/m)?.[1]?.trim();
if (header) return header;
}
} catch {
// Non-fatal; fall back to cwd basename.
}

return path.basename(cwd);
}

Expand All @@ -82,7 +97,8 @@ async function execPiMemory(
args: string[],
options?: { timeout?: number; signal?: AbortSignal }
) {
const preferred = process.env.PI_MEMORY_BIN?.trim() || path.join(process.env.HOME ?? "", ".pi", "memory", "pi-memory");
const defaultBinary = process.platform === "win32" ? "pi-memory.exe" : "pi-memory";
const preferred = process.env.PI_MEMORY_BIN?.trim() || path.join(os.homedir(), ".pi", "memory", defaultBinary);

if (preferred) {
const result = await pi.exec(preferred, args, options);
Expand Down
2 changes: 1 addition & 1 deletion native/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
CC = cc
CFLAGS = -Wall -Wextra -Wpedantic -O2 -std=c11
TARGET = pi-memory
SRC = pi-memory.c sqlite3.c
SRC = pi-memory.c sqlite3.c getopt_compat.c
INSTALL_DIR = $(HOME)/.pi/memory

$(TARGET): $(SRC) sqlite3.h
Expand Down
Loading
Loading