{"_id":"@alexleekt/pi-heading","_rev":"7-f08baf30180a20ca8533734542f01c43","name":"@alexleekt/pi-heading","dist-tags":{"latest":"0.3.1"},"versions":{"0.1.0":{"name":"@alexleekt/pi-heading","version":"0.1.0","keywords":["pi","pi-extension","heading","session-summary"],"author":{"name":"Alex Lee"},"license":"MIT","_id":"@alexleekt/pi-heading@0.1.0","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"47809b6dc36eb27ca9c801d7c4b586973b7f7562","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.1.0.tgz","fileCount":28,"integrity":"sha512-O6BNWKAcVHpvVq4fa/riQ8PbjgLriCla7JRQjOimv8MhG9AL/ImunHv2Z/tE+w4tVqZUklgcRR5avd/Y7gjS8w==","signatures":[{"sig":"MEYCIQDuTLlac4tp2kEk6pufAZ6gB6t6DzkSvN+4MimGPlse8AIhAOrDnYL2eq9O3rWrGQk1gF/ZZ3pslf5FPcIoW4tm0Rqb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":96688},"main":"index.ts","type":"module","gitHead":"cd7ba9c358aaf59b819e8877ea3fcc826d46453c","scripts":{"test":"bun test","check":"tsc --noEmit && bun test","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexleekt","email":"stratrix@gmail.com"},"_npmVersion":"11.13.0","description":"One-line session heading widget for the Pi coding agent","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-heading_0.1.0_1779297889672_0.0783407072379032","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@alexleekt/pi-heading","version":"0.1.1","keywords":["pi","pi-extension","heading","session-summary"],"author":{"name":"Alex Lee"},"license":"MIT","_id":"@alexleekt/pi-heading@0.1.1","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"92a94f3bfaccc1ecd17c8acb4922916bdbae93c5","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.1.1.tgz","fileCount":31,"integrity":"sha512-P6D6PwnwZXChLVc+tYBnFKQaj2F6ScNpGLgO1QJN/U7Fn5QxqYML1FlAdUURXhfe1lNEzjEWx9nq9dEAG+Kxdg==","signatures":[{"sig":"MEUCIARZpk7hk5ePVcUj6gloOxNgfboKx08uFRIRnphan/5NAiEAmfQGX8OVXXz3Rvs0NzDpGOVjybajfNscYxWSuSEKRDM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexleekt%2fpi-heading@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":169519},"main":"index.ts","type":"module","gitHead":"13cc8d9d14c3a2026512d660690415a68104ca4c","scripts":{"test":"bun test","check":"tsc --noEmit && bun test","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c3e9aea-0857-49e9-9a4c-ded7ca495928"}},"repository":{"url":"git+https://github.com/alexleekt/pi-extensions.git","type":"git"},"_npmVersion":"11.12.1","description":"One-line session heading widget for the Pi coding agent","directories":{},"_nodeVersion":"24.15.0","dependencies":{"@alexleekt/pi-shared":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-heading_0.1.1_1779343240988_0.12653551698564391","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@alexleekt/pi-heading","version":"0.1.2","keywords":["pi-package","pi-extension","pi","heading","session-summary"],"author":{"name":"Alex Lee"},"license":"MIT","_id":"@alexleekt/pi-heading@0.1.2","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"d5daf57a383c5aab16e66e390b4dcb1d593ec0d8","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.1.2.tgz","fileCount":31,"integrity":"sha512-cz73K5h4/qXZg+YKTprT2OuEed6cGbtNZf6lvY/4iOSBa/mbtlDfirwYLqwUUHLklLbJ9vHiJbOIZ/yViyOiPQ==","signatures":[{"sig":"MEUCIDHFR3lJkQv3GVKrVej/n9au36Guh2K4Uww/TmOw8B66AiEA1s+n/+ob5az9qGLM4W+LmtetKPtICNOwRCta9Ce6Fb0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexleekt%2fpi-heading@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":169726},"main":"index.ts","type":"module","gitHead":"31d2e634af12a9494dcca66aebfde68803dd74ca","scripts":{"test":"bun test","check":"tsc --noEmit && bun test","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c3e9aea-0857-49e9-9a4c-ded7ca495928"}},"repository":{"url":"git+https://github.com/alexleekt/pi-extensions.git","type":"git"},"_npmVersion":"11.13.0","description":"Know where you are at a glance. One-line session heading widget for the Pi agent.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"@alexleekt/pi-shared":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-heading_0.1.2_1779859175133_0.06713464711145045","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@alexleekt/pi-heading","version":"0.1.3","keywords":["pi-package","pi-extension","pi","heading","session-summary"],"author":{"name":"Alex Lee"},"license":"MIT","_id":"@alexleekt/pi-heading@0.1.3","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"f1841d2da213f7335e8f24eae4b02f33193c977f","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.1.3.tgz","fileCount":41,"integrity":"sha512-2D5A6qr3bqdje2po22KXVuAb7BNd3pr1tfriyEBzepkAH3QLxB96YlWf9iP5fK104NfOBn39d+CUaKxwaZkNwA==","signatures":[{"sig":"MEUCIG+LDBqw5L2cuVOSyt4uncBdrvNFElIs2fD9Upwk1hBAAiEAukXvdz610V0Ta+qCdFiAQxwDbXIzGRUyeeri7Vacx+s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexleekt%2fpi-heading@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":175227},"main":"index.ts","type":"module","gitHead":"d079ffb5246fe233dd2f78c7eab12e30839877b1","scripts":{"test":"bun test","check":"tsc --noEmit && bun test","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c3e9aea-0857-49e9-9a4c-ded7ca495928"}},"repository":{"url":"git+https://github.com/alexleekt/pi-extensions.git","type":"git"},"_npmVersion":"11.16.0","description":"Know where you are at a glance. One-line session heading widget for the Pi agent.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"typebox":"^0.0.1","@alexleekt/pi-shared":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-heading_0.1.3_1783197635725_0.9186914375480248","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@alexleekt/pi-heading","version":"0.2.0","keywords":["pi-package","pi-extension","pi","heading","session-summary"],"author":{"name":"Alex Lee"},"license":"MIT","_id":"@alexleekt/pi-heading@0.2.0","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"05fc3f7cd07ee77fc2bc913a7d79a70343f6834d","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.2.0.tgz","fileCount":37,"integrity":"sha512-W9htEfcB0M+fROgR6fVex+y6q7DagitTAIiqigVe0/vrsVA+R1fFSFB9HITb2+I656hWss4iS4UN/CC0O4od6g==","signatures":[{"sig":"MEYCIQCnOVZeoQzynBfjGWjpI2qkawZlkOcSOpOUom346NYQgwIhAPrTqYes4xABRmKWM5ZDatjQmKcxtRj6Umm6bSHhum7L","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexleekt%2fpi-heading@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":128097},"main":"index.ts","type":"module","gitHead":"8d7e3c73cfc7078a300e0304b921471cc25b307e","scripts":{"test":"bun test","check":"tsc --noEmit && bun test","typecheck":"tsc --noEmit","pack-smoke":"node tools/pack-smoke.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c3e9aea-0857-49e9-9a4c-ded7ca495928"}},"repository":{"url":"git+https://github.com/alexleekt/pi-extensions.git","type":"git"},"_npmVersion":"11.16.0","description":"Know where you are at a glance. One-line session heading widget for the Pi agent.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"@alexleekt/pi-shared":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"typebox":">=1.1.0","@earendil-works/pi-ai":">=0.80.0","@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":">=0.80.4"},"_npmOperationalInternal":{"tmp":"tmp/pi-heading_0.2.0_1784179994172_0.9730461247090725","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alexleekt/pi-heading","version":"0.3.0","keywords":["pi-package","pi-extension","pi","heading","session-summary"],"author":{"name":"Alex Lee"},"license":"MIT","_id":"@alexleekt/pi-heading@0.3.0","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"pi":{"extensions":["./index.ts"]},"dist":{"shasum":"0d0518276082bfaf44297dc738bf61a83c3e3847","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.3.0.tgz","fileCount":37,"integrity":"sha512-+LYetAORvZMaUV+343ee1VfU4BHoiPacR9hDQvGba7qg8BQd9hp8AT1tt9rAhl7Nzc6IADCSRXVLnrrPG5ShmA==","signatures":[{"sig":"MEYCIQCzM/Dq6TMakbtcXZqmHNvSEyUTH6oRpd+nIjr5VMm0PgIhAJHSG9aAd3zSRPEw92+OtWjgK9F2tJdsq+kX9zjpHa4y","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexleekt%2fpi-heading@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":145885},"main":"index.ts","type":"module","gitHead":"5f6a320cebc70de99e252694010fba38ea04d7b9","scripts":{"test":"bun test","check":"tsc --noEmit && bun test","typecheck":"tsc --noEmit","pack-smoke":"node tools/pack-smoke.mjs"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c3e9aea-0857-49e9-9a4c-ded7ca495928"}},"repository":{"url":"git+https://github.com/alexleekt/pi-extensions.git","type":"git"},"_npmVersion":"11.17.0","description":"Know where you are at a glance. One-line session heading widget for the Pi agent.","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@alexleekt/pi-shared":"^0.1.0"},"_hasShrinkwrap":false,"peerDependencies":{"typebox":">=1.1.0","@earendil-works/pi-ai":">=0.80.0","@earendil-works/pi-tui":"*","@earendil-works/pi-coding-agent":">=0.81.0"},"_npmOperationalInternal":{"tmp":"tmp/pi-heading_0.3.0_1787988091477_0.2590279719872586","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@alexleekt/pi-heading","version":"0.3.1","description":"Know where you are at a glance. One-line session heading widget for the Pi agent.","type":"module","main":"index.ts","scripts":{"typecheck":"tsc --noEmit","check":"tsc --noEmit && bun test","test":"bun test","pack-smoke":"node tools/pack-smoke.mjs"},"pi":{"extensions":["./index.ts"]},"dependencies":{"@alexleekt/pi-shared":"^0.1.0"},"peerDependencies":{"@earendil-works/pi-ai":">=0.80.0","@earendil-works/pi-coding-agent":">=0.81.0","@earendil-works/pi-tui":"*","typebox":">=1.1.0"},"keywords":["pi-package","pi-extension","pi","heading","session-summary"],"license":"MIT","author":{"name":"Alex Lee"},"repository":{"type":"git","url":"git+https://github.com/alexleekt/pi-extensions.git"},"homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"gitHead":"af95a81d7d337c0c1e7e55106be440c106dd4bbb","_id":"@alexleekt/pi-heading@0.3.1","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-DQlA3dIuLzc1cXSzWDwBK1B5AiXymVzJUYRRNSJXZ7VfvdmvFmZrrebQ6DRfK1zOlmMLJDw7gRaQDJKDXeBoNw==","shasum":"049a433aaaf2687f211cc791c86f760f49a9162c","tarball":"https://registry.npmjs.org/@alexleekt/pi-heading/-/pi-heading-0.3.1.tgz","fileCount":37,"unpackedSize":145782,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alexleekt%2fpi-heading@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCUNaI1pAqA2UyaAbB0hXDfHLmxjEnWX70w972qf3iPPgIgRa+5vHIq5WMd7pNmYYZc4gkLQEhyhOouCIA3QDgQ15Y="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:4c3e9aea-0857-49e9-9a4c-ded7ca495928"}},"directories":{},"maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-heading_0.3.1_1788149488312_0.1243761350596162"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-20T17:24:49.574Z","modified":"2026-08-31T04:11:28.761Z","0.1.0":"2026-05-20T17:24:49.826Z","0.1.1":"2026-05-21T06:00:41.132Z","0.1.2":"2026-05-27T05:19:35.277Z","0.1.3":"2026-07-04T20:40:35.869Z","0.2.0":"2026-07-16T05:33:14.317Z","0.3.0":"2026-08-29T07:21:31.621Z","0.3.1":"2026-08-31T04:11:28.446Z"},"bugs":{"url":"https://github.com/alexleekt/pi-extensions/issues"},"author":{"name":"Alex Lee"},"license":"MIT","homepage":"https://github.com/alexleekt/pi-extensions/tree/main/packages/pi-heading#readme","keywords":["pi-package","pi-extension","pi","heading","session-summary"],"repository":{"type":"git","url":"git+https://github.com/alexleekt/pi-extensions.git"},"description":"Know where you are at a glance. One-line session heading widget for the Pi agent.","maintainers":[{"name":"alexleekt","email":"stratrix@gmail.com"}],"readme":"# @alexleekt/pi-heading\n\n[![npm](https://img.shields.io/npm/v/@alexleekt/pi-heading)](https://www.npmjs.com/package/@alexleekt/pi-heading)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n> Know where you are at a glance.\n\nA one-line session heading for the Pi coding agent. It summarizes the current goal while Pi works, then replaces it with a short achievement when the run finishes.\n\n## What it looks like\n\n```text\nClean up the old chezmoi checkout\n```\n\nAfter completion:\n\n```text\nRemoved stale dotfiles and migrated the setup to yadm\n```\n\nThe extension uses Pi's native working-message row. There are no borders, custom panels, duplicate transcript cards, or competing animation timers.\n\n## Features\n\n| Feature | What it does |\n|---------|--------------|\n| **Auto-summarized heading** | Generates a concise goal after every user message |\n| **Achievement summary** | Shows what the agent completed after the final turn |\n| **Stable topic** | Keeps a 2–4 word topic label from jittering between related turns |\n| **Branch-aware state** | Restores the correct heading after session resume and `/tree` navigation |\n| **Native lifecycle integration** | Finalizes on Pi's `agent_settled` event, after retries, compaction, and queued follow-ups |\n| **Cancellation-aware calls** | Passes Pi's active `AbortSignal` to heading model requests |\n| **Custom prompts and model** | Supports editable prompts and automatic subscription-first model selection with manual override |\n| **Extension API** | Exposes current state through the `heading` tool and `heading:state` event |\n\n## Requirements\n\n- Pi coding agent **0.80.4 or newer**\n\n## Installation\n\n```bash\npi install @alexleekt/pi-heading\n```\n\nFor local development:\n\n```bash\nln -s ~/git/pi-extensions/packages/pi-heading ~/.pi/agent/extensions/pi-heading\n```\n\nRun `/reload` after changing extension code. Pi loads TypeScript through jiti, so clearing jiti's cache may be necessary when retargeting symlinks.\n\n## Usage\n\nThe heading updates automatically. No command is required.\n\n### `/heading`\n\nSet the current goal manually:\n\n```text\n/heading\nSession heading: Migrating from Docker to Kubernetes\n```\n\n### `/heading-model`\n\nBy default, pi-heading chooses from Pi's scoped models, preferring subscription-authenticated models before the cheapest API-key model. Use `/heading-model` to choose a manual override, or select **Automatic (subscription first)** to return to automatic selection.\n\n#### How a model is chosen\n\nEvery heading summary runs this deterministic ranking (no caching; re-evaluated per call so auth and scoping changes apply immediately):\n\n1. **Manual override** — a model picked via `/heading-model`, if still available.\n2. **Pi's scoped models** — the resolved `--models` + `enabledModels` list (`ctx.scopedModels`). Models from an enabled provider that are not listed are never used.\n3. Within that list: **subscription-authenticated (OAuth) models first** — marginal cost is already paid — tie-broken by their order in the scoped list, then provider/id.\n4. **API-key models after**, by cheapest input + output price, same tie-breakers.\n5. Fallback to the active session model if nothing matches.\n\nFor example, with `enabledModels: [\"openrouter/z-ai/glm-5.3-flash\", \"openai-codex/gpt-5.6-luna\"]` and both providers authenticated:\n\n| Rank | Model | Why |\n|------|-------|-----|\n| 1 | `openai-codex/gpt-5.6-luna` | subscription auth (OAuth) — no marginal cost |\n| 2 | `openrouter/z-ai/glm-5.3-flash` | API key — $0.325/M in+out |\n\n#### Bounded fallback\n\nSummaries run on cheap, non-critical calls, so the fallback loop is deliberately simple: the top 3 ranked candidates are tried in order; a candidate that fails auth, returns a provider error, or yields an empty summary is skipped; `AbortSignal` cancellation stops everything immediately. No health tracking or persistent demotion — the ranking is re-evaluated fresh on every call.\n\n#### Reasoning suppression\n\nHeading prompts are 12-word summaries; thinking models waste their token budget reasoning about them. The extension disables thinking natively where providers support it (Anthropic, Google), and pins `reasoning: \"low\"` for models that cannot disable thinking (e.g. GLM, GPT-5.x Codex) — verified to yield zero reasoning tokens. A 512–1024 token budget floor plus empty-result fallback guards any provider where thinking cannot be suppressed.\n\n### `/heading-debug`\n\n```text\n/heading-debug on\n/heading-debug off\n/heading-debug clear\n/heading-debug\n```\n\nDebug mode writes structured prompts, user input, responses, and errors to a private log under Pi's agent directory. The file is restricted to the current user, but it can contain sensitive conversation content; enable it only while diagnosing a problem and clear it afterward.\n\n## Agent tool\n\nThe extension registers a `heading` tool:\n\n- `action: \"get\"` returns topic, goal, and latest achievement.\n- `action: \"skill\"` returns the heading behavior guide.\n\nThe tool's prompt metadata asks the agent to check the current session goal before changing direction.\n\nThe tool is silent in the transcript: both the call and the result render as empty components, so heading checks never add visible rows to the chat.\n\n## Event bus integration\n\nOther extensions can subscribe without importing pi-heading:\n\n```typescript\npi.events.on(\"heading:state\", (payload) => {\n    const { topic, goal, achievement, mode } = payload as {\n        topic: string;\n        goal: string;\n        achievement?: string;\n        mode: \"goal\" | \"working\" | \"achievement\" | \"idle\";\n    };\n});\n```\n\nSee [PI-INTEGRATION.md](PI-INTEGRATION.md) for the payload contract.\n\n## Custom prompts\n\nPackaged defaults live in `prompts/`. To override them, create matching files under:\n\n```text\n~/.pi/agent/extensions/pi-heading/prompts/\n├── topic.md\n├── goal.md\n└── achievement.md\n```\n\nIf `PI_CODING_AGENT_DIR` is set, pi-heading follows Pi's configured agent directory instead of hardcoding `~/.pi/agent`.\n\nEach prompt supports YAML frontmatter with `max_words`:\n\n```yaml\n---\nmax_words: 4\n---\nSummarize the user's message as a concise topic label.\n\nMessage: {message}\n```\n\nPlaceholders:\n\n- `{message}` — input being summarized\n- `{goal}` — current goal, available to the achievement prompt\n- `{max_words}` — parsed frontmatter limit\n\n## Lifecycle\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Pi\n    participant Heading as pi-heading\n    participant Model as Summary model\n\n    Pi->>Heading: session_start / session_tree\n    Heading->>Heading: replay latest branch heading\n\n    User->>Pi: submit prompt\n    Pi->>Heading: before_agent_start\n    Heading->>Pi: setWorkingMessage(prompt placeholder)\n    Heading-->>Model: topic + goal (non-blocking, abort-aware)\n    Pi->>Heading: agent_start / turn_start\n    Heading->>Pi: setWorkingMessage(goal)\n\n    alt Intermediate tool turn\n        Pi->>Heading: turn_end with toolResults\n        Heading->>Heading: keep goal; skip achievement call\n    else Final text turn\n        Pi->>Heading: turn_end without toolResults\n        Heading-->>Model: achievement (non-blocking, abort-aware)\n        Heading->>Pi: setWorkingMessage(achievement)\n    end\n\n    Pi->>Heading: agent_settled\n    Heading->>Pi: keep latest goal or achievement\n```\n\n`agent_settled` is intentionally used instead of `agent_end`: Pi can retry, compact and retry, or process queued follow-ups after a low-level agent run ends.\n\n## Prompt evaluation\n\n```bash\nbun tools/prompt-eval.ts topic\nbun tools/prompt-eval.ts goal\nbun tools/prompt-eval.ts topic-goal firepass test-cases-comprehensive.json\n```\n\nThe optimizer mutates prompt files in place, so back them up first:\n\n```bash\nbun tools/prompt-eval.ts optimize topic prompts/topic.md \\\n  \"Concise 1-4 word noun phrases, no articles\" \\\n  90 firepass test-cases-comprehensive.json\n```\n\n## Development\n\n```bash\nnpm run typecheck\nnpm test\nnpm run pack-smoke\n```\n\n`pack-smoke` packs the npm artifact, verifies all transitive runtime files are present, installs it into a temporary project with declared peers, and imports the TypeScript entrypoint through Pi's jiti loader.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}