# pi-tool-wal

Write-ahead log (WAL) for [Pi](https://pi.dev) tool calls.

Before a tool runs, the extension records the **intent** (tool name, input, timestamps). After execution, it reconciles the **result** and stores the final status in a local SQLite database for audit and crash recovery.

This is **not** a transactional undo log. It does not roll back filesystem side effects. Pair it with something like git checkpoints if you need restore.

## Install

Requires **Node.js ≥ 22.5** (uses built-in `node:sqlite`).

```bash
pi install npm:pi-tool-wal
```

Or from git:

```bash
pi install git:github.com/boyuruan/pi-tool-wal
```

Local checkout:

```bash
pi install /absolute/path/to/pi-tool-wal
```

Then restart pi or run `/reload`.

## How it works

Hooks into Pi’s tool lifecycle — the model cannot skip them:

| Phase | Events | Action |
|-------|--------|--------|
| Before | `tool_execution_start`, `tool_call` | Insert/update `pending` intent |
| After | `tool_result`, `tool_execution_end` | Complete as `success` / `failed` / `partial` / `blocked` |
| Session | `session_start` / `session_shutdown` | Open DB, orphan stale pending ops |

```
LLM tool call
    → tool_execution_start   write pending
    → tool_call              refresh final input (write-ahead intent)
    → execute tool
    → tool_result            reconcile (primary)
    → tool_execution_end     complete if still pending (blocked / immediate errors)
```

## Storage

Single SQLite file:

```text
~/.pi/agent/tool-wal/wal.db
```

Logical scopes (narrow → wide):

| Scope | Key | Meaning |
|-------|-----|---------|
| session | `session_id` | One Pi conversation |
| project | `project_key` | Stable project identity |
| global | — | Entire database |

`cwd` is stored for display only; scoping uses `project_key`.

### Stable project identity

Absolute paths differ across machines. Resolution order:

1. **Explicit**
   - env `TOOL_WAL_PROJECT_ID`
   - `.pi/wal-project-id` (cwd or git toplevel)
   - `.pi/tool-wal.json` → `{ "projectId": "..." }`
2. **Git** — normalized `origin` remote + path relative to toplevel  
   Examples: `git:github.com/org/repo`, `git:github.com/org/repo#packages/api`
3. **cwd fallback** — Pi-style path encoding (machine-local)

HTTPS/SSH remotes and credentialed URLs normalize to the same host/path.

## Commands

| Command | Description |
|---------|-------------|
| `/wal` | This project summary + recent ops |
| `/wal status` | Session + project + global counts |
| `/wal pending [scope]` | Pending ops (`session` \| `project` \| `global`) |
| `/wal recent [n] [scope]` | Recent ops (default: project) |
| `/wal session` | Current session only |
| `/wal project` | All sessions in this project |
| `/wal projects` | List projects in the DB |
| `/wal global [n]` | Cross-project recent |
| `/wal show <id\|callId>` | Full record |
| `/wal orphaned [scope]` | Orphaned ops |
| `/wal prune [days] [global]` | Delete old completed rows (default: 30 days, this project) |
| `/wal path` | DB path + current project identity |
| `/wal help` | Command list |

Footer shows `wal:N pending` while the current session has in-flight ops.

## Status values

| Status | Meaning |
|--------|---------|
| `pending` | Intent recorded, no completion yet |
| `success` | Completed without error |
| `partial` | Completed with truncated/partial output |
| `failed` | Error or non-zero bash exit |
| `blocked` | Blocked before execution (e.g. permission extension) |
| `orphaned` | Left pending across crash/shutdown |

`expected_ok` flags whether completion matched the write-ahead intent (input hash, error state, etc.).

## What is covered

- Pi tool calls (built-in and extension-registered tools)

Not covered by default:

- Interactive user bash (`!` / `!!`) — uses a different event path
- Side effects outside tools

## Development

```bash
git clone https://github.com/boyuruan/pi-tool-wal.git
cd pi-tool-wal
npm test
pi install "$PWD"    # or: pi -e ./extensions/tool-wal
```

Package layout follows the [Pi package](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/packages.md) conventions (`pi` key in `package.json`).

## License

MIT
