Files
joakimp 1381a37115 Rename @mariozechner/pi-* to @earendil-works/pi-*
Pi moved to its new home at earendil-works on 2026-05-07
(https://pi.dev/news/2026/5/7/pi-has-a-new-home). Affected packages:

  @mariozechner/pi-coding-agent  -> @earendil-works/pi-coding-agent
  @mariozechner/pi-tui           -> @earendil-works/pi-tui
  @mariozechner/pi-ai            -> @earendil-works/pi-ai
  @mariozechner/pi-agent-core    -> @earendil-works/pi-agent-core

The old @mariozechner/* packages are deprecated on npm with the
explicit message 'please use @earendil-works/pi-coding-agent instead
going forward', and the version stream has moved on (old top-out
0.73.1; new currently 0.74.0). Anyone npm-installing the old names
gets a deprecation warning + a stale binary.

Sweep:
- All 7 extension TypeScript files: import statements updated.
- README, AGENTS, install.sh: textual references and the github.com/
  mariozechner/pi-coding-agent URL pointed at github.com/earendil-works/
  pi (the new monorepo root; coding-agent now lives at
  packages/coding-agent inside it).
- Bun build of mcp-loader, ext-toggle, ssh-controlmaster verified clean.

Brew install references (`brew install pi-coding-agent`) left as-is:
the homebrew formula still works at 0.73.1 and a tap update is
tracked upstream at earendil-works/pi#2755. Historical CHANGELOG
entries are untouched.
2026-05-09 17:56:15 +02:00

79 lines
2.9 KiB
TypeScript

/**
* Notify Extension
*
* Sends a native notification when the pi agent finishes and is waiting for
* input. Useful when you step away during a long task.
*
* Only fires when the agent ran for longer than --notify-min-secs (default 8).
* Short responses are silently skipped to avoid notification noise.
*
* Terminal detection (in priority order):
* KITTY_WINDOW_ID → OSC 99 (Kitty)
* WT_SESSION → Windows toast (Windows Terminal / WSL)
* otherwise → OSC 777 (iTerm2, WezTerm, Ghostty, rxvt-unicode)
*/
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
// ── Notification backends ─────────────────────────────────────────────────────
function notifyKitty(title: string, body: string): void {
// OSC 99: two-part protocol — title first, then body
process.stdout.write(`\x1b]99;i=1:d=0;${title}\x1b\\`);
process.stdout.write(`\x1b]99;i=1:p=body;${body}\x1b\\`);
}
function notifyOSC777(title: string, body: string): void {
process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
}
function notifyWindows(title: string, body: string): void {
const type = "Windows.UI.Notifications";
const script = [
`[${type}.ToastNotificationManager, ${type}, ContentType = WindowsRuntime] > $null`,
`$xml = [${type}.ToastNotificationManager]::GetTemplateContent([${type}.ToastTemplateType]::ToastText01)`,
`$xml.GetElementsByTagName('text')[0].AppendChild($xml.CreateTextNode('${body}')) > $null`,
`[${type}.ToastNotificationManager]::CreateToastNotifier('${title}').Show([${type}.ToastNotification]::new($xml))`,
].join("; ");
const { execFile } = require("node:child_process");
execFile("powershell.exe", ["-NoProfile", "-Command", script]);
}
function notify(title: string, body: string): void {
if (process.env.KITTY_WINDOW_ID) {
notifyKitty(title, body);
} else if (process.env.WT_SESSION) {
notifyWindows(title, body);
} else {
notifyOSC777(title, body);
}
}
// ── Extension ─────────────────────────────────────────────────────────────────
export default function (pi: ExtensionAPI) {
pi.registerFlag("notify-min-secs", {
description: "Minimum agent run time in seconds before a notification fires (default: 8)",
type: "number",
default: 8,
});
let startedAt: number | undefined;
pi.on("agent_start", async () => {
startedAt = Date.now();
});
pi.on("agent_end", async () => {
if (startedAt === undefined) return;
const elapsed = (Date.now() - startedAt) / 1000;
startedAt = undefined;
const minSecs = (pi.getFlag("notify-min-secs") as number | undefined) ?? 8;
if (elapsed < minSecs) return;
notify("Pi", `Done (${Math.round(elapsed)}s)`);
});
}