@ladbabynpm/picc-recap
v0.1.0
Published
Claude Code-style away summary for pi: a dim one-off 'while you were away' recap generated by a small/fast model after the agent has been idle, using Claude Code's exact prompt.
Downloads
89
Maintainers
Readme
picc-recap
Claude Code-style away summary for pi — a faithful port of
Claude Code's services/awaySummary.ts + hooks/useAwaySummary.ts.
After you step away and the agent has settled, a short, dim "while you were away" line appears. It is generated by a small/fast model from your last ~30 messages, using Claude Code's exact prompt.
This is intentionally a different thing from @zhcsyncer/pi-recap. pi-recap produces
a one-line recap + title (JSON), renames the session, and syncs a multiplexer.
picc-recap has no side effects — just the dim summary, like Claude Code.
Install
pi install npm:@ladbabynpm/picc-recapor from a git bundle / locally:
pi -e ./picc-recapFor local development the live config is a junction in ~/.pi/agent/extensions/picc-recap.
Behavior
- Trigger (auto): when the agent settles (
agent_settled), a timer starts. If you stay idle foridleAfterSettleMs(default 5 min, like Claude Code'sBLUR_DELAY_MS) with no queued work, the summary is generated. Typing anything cancels it. - Trigger (manual):
/awaygenerates immediately (with a cancellable loader). - Model: a small/fast model by default (Claude Code's
getSmallFastModel()), with thinking effectively off (smallmaxTokens). Configurable. - Display: a TUI widget below the editor, dim, prefixed with Claude Code's
※marker (U+203B, REFERENCE_MARK). Cleared as soon as you type or the agent starts. - Dedup: at most one summary per user turn (Claude Code's
hasSummarySinceLastUserTurn). - Not compaction: the summary is shown as a widget and persisted as a
customentry. It is never injected into the LLM context. - TUI only: headless modes (
print,json,rpc) are no-ops, matching Claude Code's terminal requirement.
Prompt (verbatim from Claude Code)
Session memory (broader context):
<session memory, if any>
The user stepped away and is coming back. Write exactly 1-3 short sentences. Start by
stating the high-level task — what they are building or debugging, not implementation
details. Next: the concrete next step. Skip status reports and commit recaps.The memory block is included only when present.
Config
Read from (project overrides global; project only read when the project is trusted):
$PI_CODING_AGENT_DIR/extension-data/picc-recap/config.json
<project>/.pi/extension-data/picc-recap/config.json{
"enabled": true, // master switch
"auto": true, // generate after idle (vs. /away only)
"manualCommand": true, // enable /away
"idleAfterSettleMs": 300000, // 5 minutes
"model": "small-fast", // "current" | "small-fast" | "provider/modelId"
"fallbackToCurrentModel": true,
"recentMessageWindow": 30, // Claude Code: 30
"maxTokens": 300,
"sessionMemoryPaths": [] // optional best-effort memory file(s)
}Model
model accepts:
"current"— the active session model."small-fast"(default) — picks a small/fast model from the registry (heuristic on ids containinghaiku/flash/nano/mini/small/fast/lite/instant), preferring the current provider. Falls back to the current model if none match."provider/modelId"— an exact registry lookup (e.g."Claude/claude-haiku").
Deltas from Claude Code
Pi differs from Claude Code in a few ways that cannot be replicated exactly:
- No terminal-focus detection — Claude Code triggers on terminal blur + 5 min. Pi has no focus events, so the trigger is an idle-after-settle timer of the same duration.
- No per-session memory file — Claude Code reads
{projectDir}/{sessionId}/session-memory/summary.md. Pi has no equivalent; setsessionMemoryPathsto read specific files as "broader context" (best-effort, omitted if missing — matching Claude Code's null path). - No "thinking disabled" knob in pi-ai's
complete()— emulated with a small/fast model and a smallmaxTokens. - Display is a TUI widget rather than a persistent transcript message, so it clears when you act (arguably closer to the "while you were away" intent).
Development
npm install
npm run lint && npm run typecheck && npm run testSingle test: npx vitest run test/awaySummary.test.ts
