pi-quiver 6.0.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,14 @@ Published to npm as `pi-quiver` (`pi install npm:pi-quiver`). Pushing a
8
8
  via OIDC trusted publishing. The release helper at
9
9
  `.agents/skills/release/scripts/release.sh` cuts the tag; CI publishes.
10
10
 
11
+ ## v6.0.1 - 2026-09-13
12
+
13
+ - `session-name` Herdr sink tolerates herdr-ntfy-notify's armed marker: exactly one leading `* ` on the live label no longer counts as a human rename, is preserved on every rename and on the shutdown restore, and its removal keeps the claim (#19).
14
+ - `release.sh <level>` promotes the CHANGELOG `## Unreleased` section to `## vX.Y.Z - <date>` and commits it with `package.json` in the single `Release X.Y.Z` commit; a missing or empty section fails the run. New CONFIG field `CHANGELOG_HEADING`.
15
+ - Release skill and `/release` prompt: a user instruction naming the level is the approval - no proposal step or re-confirmation; bundled follow-ups run after `verify`.
16
+ - AGENTS.md rewritten to always-on essentials plus routing; shared core bumped to v3.
17
+ - Added `.pi/gauntlet-overrides.md` (`tracker: github`, release path, write-gate carve-out for user-named writes).
18
+
11
19
  ## v6.0.0 - 2026-09-10
12
20
 
13
21
  - doc_to_md (Excel, breaking): `maxCellsPerSheet` is removed from the tool schema, CLI (`--max-cells-per-sheet`), and `quiver.docToMd` settings; a leftover key is reported by the settings lint. Sheet indices are now 0-based workbook positions covering worksheets and chartsheets, so embedded-image files move from `<stem>-s1-<n>.*` to `<stem>-s0-<n>.*` and `SheetInfo.index` is rebased.
package/README.md CHANGED
@@ -200,7 +200,7 @@ survive untouched.
200
200
 
201
201
  `sessionAutoName.enabled` makes one extra short LLM call per session (once, after the first turn) to title it; `false` (default) makes no model calls. `rules` appends house conventions to the naming prompt (later rules win when they conflict with the built-ins). Literal, case-insensitive `deny` phrases are stripped from every name; whitespace inside a phrase is loose, so `"acme corp"` also catches `AcmeCorp`. `revisitFirstTurn` re-evaluates the name once that many model round trips have completed, while `revisitEveryTurns` does so at every multiple; both default to `0` (off) because each revisit costs another short LLM call. For example, `10` and `100` mark round trips 10, 100, 200, 300. Revisits only run when the agent has fully settled (idle, nothing queued) - an automated multi-turn run such as a subagent chain is never renamed or delayed mid-flight; cadence points it crossed fire once, at the settle. A machine-generated name is replaced when stale. A name set by a human is never overwritten: the extension strongly prefers it, and announces a suggestion only when the work has clearly moved on. Counts come from the persisted transcript, so they survive resume.
202
202
 
203
- `herdrTab` (default `true`) mirrors the same curated label to the Herdr tab bar over Herdr's unix socket, independent of `ghosttyTab` - either sink can be toggled off without affecting the other. It's claim-once: the extension adopts a tab only while it still shows its default numeric label (its live 1-based position among the workspace's tabs); a manually renamed tab, or one renamed mid-session by hand, is never touched again for that session - the human's label always wins. On every shutdown (quit, reload, `/new`, resume, fork) a claimed tab's label is restored to its then-current default position, so a successor session in the same pane can claim cleanly. It only ever runs in TUI mode, on an attached TTY, under Herdr (`HERDR_ENV`/`HERDR_TAB_ID`/`HERDR_SOCKET_PATH` all set) - `pi -p`/json/rpc runs and background subagents never touch the tab. Caveats: a hard crash (`kill -9`) skips the restore and leaves the stale label - rename the tab by hand to recover; and the restored label is internally a custom name (Herdr has no clear-to-auto API), so that tab keeps a number-looking label but stops renumbering on later tab closes/reorders.
203
+ `herdrTab` (default `true`) mirrors the same curated label to the Herdr tab bar over Herdr's unix socket, independent of `ghosttyTab` - either sink can be toggled off without affecting the other. It's claim-once: the extension adopts a tab only while it still shows its default numeric label (its live 1-based position among the workspace's tabs); a manually renamed tab, or one renamed mid-session by hand, is never touched again for that session - the human's label always wins. One exception: exactly one leading `* ` (herdr-ntfy-notify's armed marker) is not a human rename - it is preserved across renames and the shutdown restore, and removing it keeps the claim. On every shutdown (quit, reload, `/new`, resume, fork) a claimed tab's label is restored to its then-current default position, so a successor session in the same pane can claim cleanly. It only ever runs in TUI mode, on an attached TTY, under Herdr (`HERDR_ENV`/`HERDR_TAB_ID`/`HERDR_SOCKET_PATH` all set) - `pi -p`/json/rpc runs and background subagents never touch the tab. Caveats: a hard crash (`kill -9`) skips the restore and leaves the stale label - rename the tab by hand to recover; and the restored label is internally a custom name (Herdr has no clear-to-auto API), so that tab keeps a number-looking label but stops renumbering on later tab closes/reorders.
204
204
 
205
205
  `fastMode` only affects `claude-opus-4-8` and `claude-opus-5` requests on Anthropic's `anthropic-messages` API; enabling it opts into premium fast-mode pricing. `--fast` forces it on for one launch; `/fast on|off` toggles live. Proxy providers (opencode, cloudflare-ai-gateway) are excluded. `fastMode`'s header injection needs the `before_provider_headers` hook (pi bundling `@earendil-works/pi-coding-agent` >= 0.80.5); on older pi the beta header is silently not sent. The `anthropic-beta` header is discovered at request time by probing pi's own request assembly (no network), so conditional betas pi adds - e.g. `server-side-fallback-2026-07-01` for models with server-side fallback - are preserved alongside `fast-mode-2026-02-01`. If the probe fails, the header falls back to the static OAuth-identity + fast-mode list. See [doc/fetch.md](doc/fetch.md) and [doc/doc-to-md.md](doc/doc-to-md.md) for the ingestion tools' full reference; session-name/sword-header behavior above is complete.
206
206
 
@@ -392,7 +392,9 @@ bash .agents/skills/release/scripts/release.sh patch # or minor / major
392
392
  bash .agents/skills/release/scripts/release.sh --dry-run patch
393
393
  ```
394
394
 
395
- It bumps `package.json`, commits `Release <version>`, runs the tests, creates
396
- and pushes the `vX.Y.Z` tag, then monitors the publish. See
397
- `.agents/skills/release/SKILL.md` for the full flow (`sync-presets` migrates
398
- old git-tag pins to `npm:pi-quiver@<version>`).
395
+ It promotes the `## Unreleased` CHANGELOG section to `## vX.Y.Z - <date>`,
396
+ bumps `package.json`, commits `Release <version>`, runs the tests, creates and
397
+ pushes the `vX.Y.Z` tag, then monitors the publish. See
398
+ `.agents/skills/release/SKILL.md` for the full flow (`sync-presets --apply`
399
+ rewrites same-form `npm:pi-quiver@<old>` pins; git-tag pins are reported for
400
+ manual migration).
@@ -498,8 +498,10 @@ export function installSessionName(pi: ExtensionAPI, generate: NameGenerator = g
498
498
 
499
499
  // Herdr sink. Claim-once: adopt the tab only while it shows its default
500
500
  // (position) label; a human rename - before or during the session - wins
501
- // permanently. All syncs serialize on one chain so overlapping hooks never
502
- // interleave a read with a rename.
501
+ // permanently. The one exception is exactly one leading "* ": that is
502
+ // herdr-ntfy-notify's armed marker, ignored for ownership and carried
503
+ // through on every write. All syncs serialize on one chain so overlapping
504
+ // hooks never interleave a read with a rename.
503
505
  // Used both for turn_start syncs (bounds a wedged-but-accepting Herdr so it
504
506
  // can't stall the turn) and for the session_end restore.
505
507
  const HERDR_TIMEOUT_MS = 500;
@@ -511,6 +513,13 @@ export function installSessionName(pi: ExtensionAPI, generate: NameGenerator = g
511
513
  return siblings.findIndex((t) => t.tab_id === tabId) + 1;
512
514
  };
513
515
 
516
+ const ARMED_PREFIX = "* ";
517
+ const matchOwned = (live: string, expected: string): { owned: boolean; armed: boolean } => {
518
+ if (live === expected) return { owned: true, armed: false };
519
+ if (live === ARMED_PREFIX + expected) return { owned: true, armed: true };
520
+ return { owned: false, armed: false };
521
+ };
522
+
514
523
  const syncHerdrTab = (cfg: Config, label: string | null, mode: Mode | undefined): Promise<void> => {
515
524
  const run = async (): Promise<void> => {
516
525
  if (!cfg.herdrTab || mode !== "tui" || !label) return;
@@ -524,23 +533,25 @@ export function installSessionName(pi: ExtensionAPI, generate: NameGenerator = g
524
533
  const position = positionOf(tabs, tabId);
525
534
  if (position === -1) return; // stale tab id (pane moved); retry harmlessly
526
535
  const own = tabs.find((t) => t.tab_id === tabId)!;
527
- if (own.label !== String(position)) {
536
+ const owned = matchOwned(own.label, String(position));
537
+ if (!owned.owned) {
528
538
  herdrClaim = "backed-off"; // human (or crashed predecessor) owns it
529
539
  return;
530
540
  }
531
- if (await renameTab(sock, tabId, label, HERDR_TIMEOUT_MS)) {
541
+ if (await renameTab(sock, tabId, (owned.armed ? ARMED_PREFIX : "") + label, HERDR_TIMEOUT_MS)) {
532
542
  herdrClaim = { lastWritten: label };
533
543
  }
534
544
  return;
535
545
  }
536
546
  const live = await getTab(sock, tabId, HERDR_TIMEOUT_MS);
537
547
  if (!live) return; // failed read is not a human rename; stay claimed
538
- if (live.label !== herdrClaim.lastWritten) {
548
+ const owned = matchOwned(live.label, herdrClaim.lastWritten);
549
+ if (!owned.owned) {
539
550
  herdrClaim = "backed-off";
540
551
  return;
541
552
  }
542
553
  if (label === herdrClaim.lastWritten) return;
543
- if (await renameTab(sock, tabId, label, HERDR_TIMEOUT_MS)) herdrClaim.lastWritten = label;
554
+ if (await renameTab(sock, tabId, (owned.armed ? ARMED_PREFIX : "") + label, HERDR_TIMEOUT_MS)) herdrClaim.lastWritten = label;
544
555
  };
545
556
  herdrChain = herdrChain.then(run, run);
546
557
  return herdrChain;
@@ -555,12 +566,14 @@ export function installSessionName(pi: ExtensionAPI, generate: NameGenerator = g
555
566
  const sock = process.env.HERDR_SOCKET_PATH as string;
556
567
  const tabId = process.env.HERDR_TAB_ID as string;
557
568
  const live = await getTab(sock, tabId, HERDR_TIMEOUT_MS);
558
- if (!live || live.label !== herdrClaim.lastWritten) return; // human's label wins
569
+ if (!live) return;
570
+ const owned = matchOwned(live.label, herdrClaim.lastWritten);
571
+ if (!owned.owned) return; // human's label wins
559
572
  const tabs = await listTabs(sock, HERDR_TIMEOUT_MS);
560
573
  if (!tabs) return;
561
574
  const position = positionOf(tabs, tabId);
562
575
  if (position === -1) return;
563
- await renameTab(sock, tabId, String(position), HERDR_TIMEOUT_MS);
576
+ await renameTab(sock, tabId, (owned.armed ? ARMED_PREFIX : "") + String(position), HERDR_TIMEOUT_MS);
564
577
  };
565
578
  herdrChain = herdrChain.then(run, run);
566
579
  return herdrChain;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-quiver",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "description": "Personal pack of Pi coding-agent extensions: context-safe fetch, doc_to_md PDF/DOCX/PPTX-to-Markdown conversion, session naming, a themed ASCII startup header, Opus 4.8 fast mode, and a provider-stall watchdog.",
5
5
  "author": "Jacek Juraszek",
6
6
  "license": "MIT",