punched-memory

extensionmaintained

Persistent per-directory project memory for the pi coding agent. Keeps a structured pi.md file in each cwd, private & gitignored, that captures scope / decisions / gotchas / todos / session history across sessions.

by — · v1.0.4 · published 3w ago

$ pi install npm:punched-memory
downloads/mo
834
stars
0
last push
3w ago
open issues
0

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

845 downloads · last 12 weeks (weekly)

README

punched — package for pi agent

🪡 punched-memory

Persistent per-directory project memory for the pi coding agent.
A structured pi.md in every working directory — private, gitignored, recoverable across sessions.

MIT License pi-extension TypeScript strict 9 languages 3 runtime deps


punched-memory (alias: punched) keeps a structured pi.md file in every working directory you use with pi. The file is private — it is auto-added to .gitignore whenever the directory is a git repo — and stores the entire project memory across sessions: scope, decisions, gotchas, TODO checklist and a per-session working log. Content is written in the user's interaction language (auto-detected or explicitly chosen) and includes session IDs, timestamps, and structured sub-sections so a fresh session can recover context immediately.

When you re-enter a directory, punched keeps the existing pi.md so context is available, but it does not interrupt you with a recall prompt by default. When you want to browse or inject a past session summary into the editor, run /punched session (or pick the Recall previous sessions entry from the main menu). You can flip the auto-prompt back on via /punched-memory config → Recall prompt.

🛡️ Safety guard: pi.md is a per-working-directory file. If pi is started from the filesystem root (/) — or the configured filename tries to escape the cwd (../x.md, absolute paths, nested paths) — punched refuses to touch that location and disables itself for the session with a warning instead of crashing on an EACCES write. Start pi from a real project directory to get memory.


✨ Features

🪡 pi.md per cwdone file, stable structured format with YAML front-matter and well-known sections
🧠 Decisions logdate, why, trade-offs and alternatives (as a markdown list)
⚠️ Gotchastitle + description + date, easy to grep later
✅ TODO checklistsplit into Pending / Done, toggleable by id
📝 Session logid, start/end timestamps, title, summary, decisions, files, open questions
🌍 i18n9 languages (en, es, fr, de, it, pt, ja, zh, ru); auto-detect or explicit
🎨 Visual TUIanimated banner, needle spinner, boxed menus, recall view, config
🔒 Private by defaultauto-patches .gitignore in git repos (also for .punched-memory.json)
🤖 LLM toolspunched_log, punched_todo, punched_session, punched_recall
💾 Layered configglobal ~/.pi/agent/punched-memory/config.json + per-project .punched-memory.json
🪝 Manual recall/punched session opens the recall view, no auto-interrupt
🛡️ Strict TypeScriptfull strict mode, zero any in public APIs

📦 Install

One-line install

pi install git:github.com/noguerol/punched

That's it. Reload pi with /reload and punched will be active on the next session start.

From a local clone (development)

git clone https://github.com/noguerol/punched
cd punched
npm install
ln -sfn "$(pwd)" ~/.pi/agent/extensions/punched-memory

Then /reload in pi.

From npm (when published)

pi install npm:punched-memory

🎯 Commands

All commands also work under the /punched alias.

CommandDescription
/punched-memoryOpen the visual main menu (status, recall, log, todos, config)
/punched-memory configOpen the configuration menu (toggles, language, filename)
/punched-memory statusShow pi.md stats (sessions, decisions, todos, language)
/punched-memory sessionOpen the recall view — browse previous sessions and inject any into the editor
/punched-memory recallAlias for session
/punched-memory log <note>Append a free-form note to the current session
/punched-memory language <code>Set language: auto, en, es, fr, de, it, pt, ja, zh, ru
/punched-memory forgetPermanently delete pi.md (with confirmation)
/punched-memory helpShow command help

🤖 LLM-callable tools

The extension registers four tools the model can call proactively. They have custom TUI renderers so you can see at a glance what the model added.

punched_log

Append a structured entry. Type can be:

TypeRequiredOptionalDescription
decisiontitlebody (why), alternativesa key design decision
gotchatitlebody (description)a trap to remember
taskbodya new TODO item
donebodymark a matching TODO as done
notebodya note appended to the current session
questionbodyan open question for the current session
scopebodyappend/merge to the project scope
goallistreplaceappend or replace the goals list
non_goallistreplaceappend or replace the non-goals list
techlistreplaceappend or replace the tech-stack list
componentlistreplaceappend or replace the components list

punched_todo

Manage the project TODO checklist: add (text), toggle (id), list, clear.

punched_session

Update the current session: checkpoint / end / update, with optional title, summary, decisions, files, questions, notes.

punched_recall

Read the project's pi.md so the model can recover context between sessions. Returns a structured markdown view.


⚙️ Configuration

Configuration is layered — per-project overrides win over global:

  • Global: ~/.pi/agent/punched-memory/config.json
  • Per-project: <cwd>/.punched-memory.json (always gitignored)

Open /punched-memory config to edit visually.

SettingDefaultDescription
enabledtrueMaster switch — when off the extension is dormant
showBannertrueShow the 🪡 banner on session start
promptRecallfalseWhen true, prompt to recall previous sessions on session start. Off by default — use /punched session instead.
autoGitignoretruePatch .gitignore when in a git repo (covers pi.md and .punched-memory.json)
autoLogtruePersist session markers automatically
footerStatustrueShow a 🪡 indicator in the footer
llmToolsEnabledtrueAllow the model to call the punched_* tools
languageautoauto (detect from your messages) or an explicit code
mdStylefullfull or compact markdown rendering
maxSessionHistory50Number of sessions kept on disk
filenamepi.mdOn-disk memory file name (don't change unless you must)

📄 On-disk format

The on-disk file is plain Markdown — easy to cat, grep, search, or read directly. punched_recall parses it back into structured form for the LLM.

---
punched-version: 1
project: my-cool-app
language: en
created: 2025-01-15T10:00:00.000Z
lastUpdated: 2025-01-15T16:45:00.000Z
sessions:
  - id: 9c3a1e8b-…
    started: 2025-01-15T10:00:00.000Z
    ended: 2025-01-15T16:45:00.000Z
    title: "Refactor auth flow"
---

# 🪡 pi.md — Project Memory

> Persistent project memory generated by `punched-memory`. This file is **private**…

## 📋 Project Scope
Real-time chat with WebSockets, E2E encryption, offline-first sync.

### Goals
- ship v1 to 1000 users
- p99 latency < 100ms

### Non-goals
- native mobile in v1

## 🏗️ Architecture & Stack
### Tech Stack
- Rust, WebSockets, SQLite, WASM

### Key Components
- chat-server, crypto-layer, sync-engine

## 🧠 Decisions Log
### 2025-01-15 — E2E via libsodium
**Why:** privacy is hard requirement

**Alternatives considered:**
- TLS only
- custom AES

## ⚠️ Gotchas & Pitfalls
- **WS reconnect storms**: on network flap, clients retry too aggressively; add jittered backoff (`2025-01-15`)

## ✅ Tasks & TODO Checklist
### Pending
- [ ] benchmark p99 latency

### Done
- [x] write protobuf schema

## 📝 Working Session Log
### 🪡 Session <id> — 2025-01-15 10:00 → 16:45
**Title:** Refactor auth flow
**Summary:**
…

#### Decisions made this session
#### Files touched
#### Open questions

Note: section headings are always written in English so the parser can reliably round-trip the file. Prose inside sections (decisions, gotchas, summaries, …) is written in your language.


🎨 Visual TUI

The extension goes out of its way to feel warm and friendly:

  • 🪡 Needle-and-paper spinner during every save (["🪡","▪","🪡","▪","🎴","▪"])
  • 🎨 Boxed banner on session start with project name, session count, language, last-updated timestamp and status pill (🪡 (on) / 🪡 off)
  • 🧠 Recall view — scrollable cards for each past session with title, dates, summary, decisions. Press Enter to inject the selected session into the editor
  • 📋 Visual menus — main menu, status panel, recall list, config menu with emoji-labelled toggles
  • 🇪🇸 / 🇬🇧 / 🇫🇷 / … — banner headings and intro adapt to the active language
  • ✨ Compact footer indicator (🪡 (on) / 🪡 off) — same emoji, tiny on/off label; shows off when the extension is disabled or no pi.md exists yet

🔒 Privacy & safety

  • pi.md is never committed to git — the extension patches .gitignore automatically the first time you open a git repo. The per-project override file .punched-memory.json is similarly guarded.
  • All content stays on your machine. No network calls, no telemetry.
  • The global config lives at ~/.pi/agent/punched-memory/config.json, inside your trusted pi config dir.
  • The extension only reads/writes files inside the working directory and your pi config dir.

🛠️ Development

git clone https://github.com/noguerol/punched
cd punched
npm install              # for type-checking only — jiti runs TS directly
npx tsc --noEmit         # full strict type-check

To hot-reload after edits, run /reload in pi. The extension has three runtime dependencies (@earendil-works/pi-*, typebox) and zero on any other package.

Source layout

src/
├── index.ts        — main entry: command registration, session lifecycle
├── config.ts       — global + per-project config (load / save / patch)
├── pimd.ts         — read / parse / serialize the pi.md document
├── language.ts     — lightweight language detector (no external deps)
├── i18n.ts         — localized strings for the TUI & on-disk headings
├── gitignore.ts    — auto-guard pi.md inside git repos
├── tools.ts        — LLM-callable punched_* tools
└── ui/
    ├── banner.ts        — animated banner (box-drawing + emojis)
    ├── spinner.ts       — needle-and-paper spinner
    ├── main-menu.ts     — visual main menu (custom component)
    ├── recall-view.ts   — scrollable recall cards
    └── config-menu.ts   — toggles, language, filename, etc.

🤝 Contributing

Issues and PRs welcome. Please:

  1. Open an issue first to discuss non-trivial changes
  2. Keep tsc --noEmit clean
  3. Add or update tests when relevant
  4. Match the existing code style (strict TS, no any, named exports)

📋 License

MIT — © 2026 punched-memory contributors


🧵 Credits

Inspired by classic "punched tape" memories — the project memory is stitched together session by session, one needle-and-thread stitch at a time. 🪡

Built for the pi coding agent.