[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-95918":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":14,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":14,"starSnapshotCount":14,"syncStatus":31,"lastSyncTime":32,"discoverSource":33},95918,"pi-posthorse","fitchmultz\u002Fpi-posthorse","fitchmultz","Posthorse: fresh context, same journey. Native no-summary context windows for the fitchmultz\u002Fpi fork of the Pi coding agent, with rollover tools, durable notes, and history recovery.",null,"TypeScript",198,4,1,0,48,2.1,"MIT License",false,"main",true,[22,23,24,25,26,27],"coding-agent","context-window","llm","pi","pi-extension","pi-package","2026-09-21 02:04:29","# Posthorse\n\n**Fresh context. Same journey.** (POST-horse)\n\nNative, no-summary context windows for the [`fitchmultz\u002Fpi`](https:\u002F\u002Fgithub.com\u002Ffitchmultz\u002Fpi) fork of [Pi](https:\u002F\u002Fgithub.com\u002Fearendil-works\u002Fpi). A post-horse was swapped in at relay stations so the courier and the message could continue on fresh legs. Posthorse does the same for a model: fresh context, same work, complete recoverable transcript.\n\n![Posthorse flow](https:\u002F\u002Fraw.githubusercontent.com\u002Ffitchmultz\u002Fpi-posthorse\u002Fmain\u002Fdiagram.png)\n\nPi owns the persisted boundary. Posthorse owns the policy: stable window guidance, one best-effort checkpoint reminder, `new_context`, `get_context_remaining`, durable `notes`, and window-aware `history`. A rollover removes the old window from active model context while the JSONL transcript stays append-only and complete.\n\n## Requirements\n\n- Node `>=22.19.0`.\n- The `fitchmultz\u002Fpi` fork. The CI baseline is `f9b06177e565f70cd243a785d088d1c491830dbd` (Pi `0.85.0`). Posthorse needs the fork's native `context_window` entries, its `session_before_auto_compact` hook, and `ctx.getCompactionSettings()`.\n- Official, unpatched Pi is unsupported. Posthorse reports a clear extension error at session start and cannot operate; Pi itself keeps running.\n\n## Install\n\nBuild the fork:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Ffitchmultz\u002Fpi.git\ncd pi\ngit checkout f9b06177e565f70cd243a785d088d1c491830dbd\nnpm install --ignore-scripts\nnpm run build\n```\n\nAfter updating the fork, run the install and build commands again, then restart Pi. `pi --version` reads the checkout's package metadata, so it does not prove that the updated source has been built.\n\nRun it as `node packages\u002Fcoding-agent\u002Fdist\u002Fbundle\u002Fcli.js`, or run `npm link` inside `packages\u002Fcoding-agent` so that build becomes your `pi` command.\n\nThen install Posthorse with that `pi`:\n\n```bash\npi install git:github.com\u002Ffitchmultz\u002Fpi-posthorse        # from Git; add @\u003Ctag> to pin a release\npi install npm:pi-posthorse                             # from npm\npi -e git:github.com\u002Ffitchmultz\u002Fpi-posthorse              # try it for one run without installing\n```\n\nUpdate with `pi update npm:pi-posthorse` or `pi update --extensions`; move a pinned Git install with `pi install git:github.com\u002Ffitchmultz\u002Fpi-posthorse@\u003Cnew tag>`. Uninstall with `pi remove npm:pi-posthorse` (or the Git source you installed). Removing the package leaves `.pi\u002Fnotes` and Pi's session history in place.\n\nAfter installing or updating Posthorse, run `\u002Freload` in existing Pi sessions or restart them to load the new version.\n\nKeep exactly one copy loaded. `pi list` shows every package source; if an older entry such as `git:github.com\u002Ffitchmultz\u002Fpi-headroom.git` or a local checkout is still listed, `pi remove` it before installing the npm package, otherwise two copies register the same tools and compete for the same rollover hook.\n\n## How it works\n\n1. **Stable guidance.** Window behavior is part of the system prompt. There is no per-request meter to churn the prompt.\n2. **One best-effort checkpoint.** While Pi compaction is enabled, one reminder may appear shortly before Pi's rollover line. A large turn, overflow, restart, or smaller model can reach rollover without it. Reminders are fingerprinted by window, context size, and reserve, so switching to a different context size gets a fresh reminder and stale ones are filtered from model input.\n3. **`get_context_remaining`.** Reports the best available native estimate of tokens until Pi's automatic rollover line and until the model's hard limit. Pi's value is an estimate until the active model reports usage.\n4. **`new_context`.** Requests an atomic rollover after the complete tool batch succeeds. An optional handoff is persisted and becomes the first state of the fresh window. If a sibling tool in the same batch fails, Pi does not commit the boundary; the checkpoint reminder still applies.\n5. **Automatic rollover without summaries.** With a supported context budget and room for a recovery record, Posthorse claims Pi's automatic threshold and overflow trigger through `session_before_auto_compact`, before Pi resolves summarization credentials or prepares a summary. Oversized first turns and tool results can then roll over even without summarization credentials. Otherwise Pi's own compaction remains in control. Manual `\u002Fcompact` is unchanged.\n6. **Bounded recovery record.** The automatic handoff keeps direct user inputs, `ask_question` outcomes, visible coordination messages, and the trailing tool batch that no model has consumed yet (call arguments, bounded result text, and the entry ids to recover the rest). A clearly labeled, possibly stale older checkpoint comes last, after the current inputs and unseen results. Older assistant prose and consumed tool results are not treated as state. Newly submitted input stays separate and is saved after the boundary, not copied into the handoff.\n7. **`notes` and `history`.** Notes live with the repository root, shared across linked worktrees. History searches normalized transcript text and returns stored images for a requested entry.\n\nAt turn end, Posthorse checks whether usage is in the reminder band before explicitly looking up the full branch. Context filtering skips its branch lookup when model input contains neither `posthorse-reminder` nor legacy `headroom-reminder` messages. History searches, reads, and recovery remain available with no new limits.\n\nAutomatic recovery is an emergency input record, not proof of progress. The fresh model is told to restore notes and todo state, inspect history when needed, and verify live state before taking stateful or external action.\n\n## Settings\n\nPosthorse follows Pi's effective `compaction` settings, including Pi's decision about whether project settings are trusted. Disabling `compaction.enabled` disables reminders and automatic rollover; `new_context` stays available.\n\nThe model's context window minus `compaction.reserveTokens` must leave at least 10,000 usable tokens. Below that (for example an 8K or 16K model with the default 16,384 reserve) Posthorse reports an unsupported configuration in the guidance and in `get_context_remaining`, turns automatic behavior off for that model, and leaves Pi's own compaction in place. Lower the reserve or use a larger model. The checkpoint reminder band is the last 10% of usable context, capped at 32,000 tokens, so a large reserve cannot trigger a reminder immediately in a fresh window.\n\nExplicit and automatic handoffs are capped at 20,000 characters and half the active model's fresh operational capacity after prompt\u002Ftool overhead and any pending input, whichever is smaller. Oversized explicit handoffs are rejected with an instruction to save fuller state in notes; automatic rollover stays with Pi when no safe recovery record fits. When usage is not known yet, notes and history pages use the same model-aware limit.\n\nOnly one automatic compaction or rollover policy extension should be enabled at a time. Pi keeps the last non-cancel result from multiple handlers of the same hook, so load order would otherwise decide which policy wins.\n\n## Tools\n\n- `new_context({ handoff? })`\n- `get_context_remaining()`\n- `notes({ op, ... })`: `list`, `read` (paged; `offset` continues), `write` (empty content clears), `append` (one atomic newline-terminated record), `search` (excerpts centered on the match)\n- `history({ op, ... })`: `search`, `read`; results carry native window ids, reads return stored images with the first page and the next character offset when text remains\n\nRead pages, including returned images, shrink to the context that is actually left. Before usage is known, they reserve prompt\u002Ftool overhead and leave half the rest free. Unsafe pages are refused with the offset preserved; call `new_context` and retry.\n\n`history search` puts matching original content before recovery material: handoffs, compaction and branch summaries, checkpoint reminders, and `notes`, `new_context`, and `history` calls\u002Fresults. Ordinary prose or another tool call in the same assistant entry keeps its priority when that content matches. Every entry remains searchable; `history read` returns the complete normalized entry, including any recovery content omitted from a search excerpt.\n\nWithin each group, current-branch matches are newest first. With `all: true`, Posthorse searches every session file in the active Pi session directory, newest-modified sessions first and newest entries within each session; this is not a global timestamp sort. The result limit applies after priority, so newer echoes cannot displace older original matches. Entries copied by a fork are reported once.\n\nNotes live in `.pi\u002Fnotes\u002F` at the repository root (the main checkout for a linked worktree, the current directory outside Git). Add the directory to `.gitignore` when the project should not track it.\n\n## Data and privacy\n\n- Posthorse makes no network requests.\n- Notes are plaintext files under `.pi\u002Fnotes`. They survive package removal and may be committed unless ignored.\n- `history` with `all: true` scans nested JSONL files in the active Pi session directory, including subagent sessions.\n- History can return user text, assistant text and thinking, tool arguments and results, handoffs, custom messages, and images. Direct shell entries Pi marked `excludeFromContext` come back as a placeholder only.\n- Returned history content enters the currently selected model and provider context.\n- Removing Posthorse does not remove notes or Pi session history.\n\n## Compatibility\n\nReminders persisted by pi-headroom (`headroom-reminder`) are recognized alongside `posthorse-reminder` for deduplication, filtering, and recovery records. Notes, tool names, `.pi\u002Fnotes`, and Pi's `context_window` entries are unchanged.\n\n## Develop\n\n```bash\nnpm ci\nnpm test\nnpm run check\nPI_FORK=..\u002Fpi scripts\u002Fintegration.sh   # loads the real extension into the fork's test harness (fork built)\n```\n\n`npm run check` type-checks `index.ts` and the unit tests; the integration test runs inside the fork's harness. Unit tests cover reminder boundaries, skipped branch lookups, and legacy reminders; native integration tests cover rollover and history recovery. CI runs the unit tests on Node 22.19 and 24, `npm audit`, `npm pack --dry-run`, and the integration job against the pinned fork revision.\n","Posthorse 是一个为 fitchmultz\u002Fpi 分支定制的上下文管理扩展，旨在解决大语言模型在长周期编程任务中上下文窗口受限与历史丢失的问题。它提供原生、无摘要的上下文窗口机制，支持上下文滚动更新（rollover）、持久化笔记（durable notes）、完整可恢复的历史记录（append-only JSONL transcript），并集成于 Pi 编码代理的生命周期钩子中。核心特点包括稳定窗口策略、上下文剩余量查询、会话级上下文隔离及故障后历史重建能力。适用于需长时间连续交互、多步骤代码生成与调试的本地 LLM 编程场景，尤其适合基于 Pi 框架构建的离线\u002F私有化开发助手。",2,"2026-09-06 02:30:05","CREATED_QUERY"]