diff --git a/AGENTS.md b/AGENTS.md index 60d38ea..5e6e869 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,25 +6,77 @@ Use `[type/name] Message` format for commits: - `[extensions/goal] Add a token budget to goal continuation` - `[skills/shell] Add shell skill` -- `[prompts/commit] Add commit message prompt` - `[themes/catppuccin] Tweak accent color` -## README in lockstep +## README -When adding, changing, or removing anything user-facing (extension, skill, prompt, theme), update the matching section of `README.md` in the same commit. Each item gets a short entry: what it does and how to invoke it. Never leave a new artifact undocumented. +When adding, changing, or removing anything user-facing (extension, skill, prompt, theme), update `README.md` in the same commit. The root README is an **index, not a manual**: one bullet per artifact — -## Docs +```markdown +- [name](./path) - one clause on what it does. +``` -Three layers, each with one job: +— and nothing else. Usage, flags, configuration, examples, troubleshooting, and credits belong in the artifact's own docs, never in the root index. -- **Root `README.md`** — the user-facing index. Every artifact gets a short entry: what it does, how to invoke it, and a link to its own docs when it has them. It is not the only home for setup detail. -- **Item-local `README.md`** (e.g. `skills/kagi/README.md`) — human-facing setup, configuration, and troubleshooting for that artifact. Not agent context; safe to keep long. -- **`SKILL.md`** — agent-facing usage only. No human setup instructions. +Where those docs live: -Update every layer the change touches in the same commit. New artifacts get a root README entry and, if they need setup, an item-local README. +- **Skills** — `skills//README.md` for human-facing setup, configuration, invocation, and troubleshooting (every skill gets one, because the root entry links it). `SKILL.md` stays agent-facing usage only: no setup instructions, no credits. +- **Everything else** — the source file, whose header comment carries usage and attribution; add an item-local `README.md` when the artifact needs more prose than a docstring should hold, and point the root entry at it instead. -## Skill paths +Every layer a change touches updates in the same commit. -In `SKILL.md`, refer to bundled scripts by paths relative to the skill's own directory -(`./search.mjs`), following Pi's skill docs. Pi advertises each skill's location and performs -no `{baseDir}`-style substitution, so do not reintroduce that placeholder. +## Credits + +Every derived or adapted artifact carries one credit sentence, in one fixed format, plus a matching `NOTICE` entry. The sentence is always: + +```text + from [/ ``]() () — . +``` + +- **Verb.** `Copied from` — used verbatim. `Derived from` — substantial original code or prose retained. `Inspired by` — structure or idea only. +- **Label.** `/` plus the backticked path of the file it came from. Never a description of the source ("mitsuhiko's github skill") in place of the path. +- **Link.** A blob/permalink to the original file. Docs sites and repo roots are not acceptable substitutes when a file link exists. +- **License.** The upstream license id, with the copyright line for MIT-style licenses: `(MIT, Copyright (c) 2026 Madeleine Ostoja)`. +- **Modification clause.** Em-dash, then what we changed; omit the clause entirely when nothing changed. Keep it to the substantive deltas, not a changelog. + +Placement — exactly one human-facing home per artifact: + +| Artifact | Where the sentence goes | +| --- | --- | +| A single file (extension `.ts`, prompt `.md`) | Final paragraph of the file's header comment | +| Has an item-local `README.md` (skills; extensions that grow one) | Final `## Credits` section there | +| Cannot carry a comment (JSON themes) | `NOTICE` only | + +A single-file extension needs no README just to hold a credit — the header comment is the normal home, and it already carries the usage the root index no longer repeats. Grow an item `README.md` when the artifact needs setup, configuration, or troubleshooting prose; move the credit there at that point and leave a pointer in the header. + +In a `README.md` (`## Credits` is the last section, the sentence is its whole body): + +```markdown +## Credits + +Inspired by [badlogic/pi-skills `brave-search/search.js`](https://github.com/badlogic/pi-skills/blob/main/brave-search/search.js) (MIT, Copyright (c) 2024 Mario Zechner) — same single-file CLI shape, rewritten against the Kagi API with OS-keyring key lookup. +``` + +In a file header comment (same sentence, Markdown kept, hard-wrapped with ` * `): + +```ts + * Derived from [mitsuhiko/agent-stuff + * `extensions/goal.ts`](https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/goal.ts) + * (Apache-2.0) — session-log-backed state instead of an external database. + */ +``` + +`NOTICE` is the legal record and lists every derived file regardless of where the human-facing sentence sits. Its shape is fixed — artifact path, then a ` from / ():` line, then the URL on its own line, then `Modified:`: + +```text +extensions/goal.ts + Derived from mitsuhiko/agent-stuff (Apache-2.0): + https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/goal.ts + Modified: session-log-backed state; optional token budget; stricter audits. +``` + +Update the credit sentence and its `NOTICE` entry in the same commit as the artifact they describe. + +## Pi documentation + +Before customizing or extending Pi itself — extensions, skills, prompt templates, themes, TUI components, keybindings, packages, the SDK — read Pi's docs instead of working from memory or guessing at APIs. Pages are hosted at `https://pi.dev/docs/latest/` (e.g. `.../latest/skills` for skill creation) and ship bundled with the installed binary: resolve `docs/.md` and `examples/` under Pi's install directory, found via `dirname "$(readlink -f "$(command -v pi)")"`. Follow a page's cross-references before implementing, and treat upstream docs as authoritative over the conventions here. diff --git a/NOTICE b/NOTICE index 6876331..b382b53 100644 --- a/NOTICE +++ b/NOTICE @@ -6,28 +6,33 @@ This product includes software derived from the following third-party projects, each retaining its original license: extensions/notify.ts - Derived from mitsuhiko's agent-stuff (Apache-2.0): + Derived from mitsuhiko/agent-stuff (Apache-2.0): https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/notify.ts Modified: simplified to OSC 777 notifications only. extensions/goal.ts - Derived from mitsuhiko's agent-stuff (Apache-2.0): + Derived from mitsuhiko/agent-stuff (Apache-2.0): https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/goal.ts + Modified: session-log-backed state instead of an external database; optional + token budget; stricter completion and blocked audits. extensions/handoff.ts - Taken from pi's extension examples (MIT, Copyright (c) earendil-works): - https://pi.dev/docs/extensions + Copied from earendil-works/pi (MIT, Copyright (c) earendil-works): + https://github.com/earendil-works/pi/blob/main/packages/coding-agent/examples/extensions/handoff.ts themes/catppuccin-frappe.json - Taken from pi-catppuccin (MIT, Copyright (c) 2026 Madeleine Ostoja): + Derived from madeleineostoja/pi-catppuccin (MIT, Copyright (c) 2026 Madeleine Ostoja): https://github.com/madeleineostoja/pi-catppuccin/blob/main/themes/catppuccin-frappe.json + Modified: mauve accent, quiet surface/overlay chrome, thinking gradient. skills/github/SKILL.md - Derived from mitsuhiko's agent-stuff (Apache-2.0): + Derived from mitsuhiko/agent-stuff (Apache-2.0): https://github.com/mitsuhiko/agent-stuff/blob/main/skills/github/SKILL.md Modified: states the auth rationale, the repo-targeting, output-projection, CI-log, gh api, and write-confirmation habits; defers details to gh --help. skills/kagi/{search,extract}.mjs - CLI structure inspired by badlogic's pi-skills brave-search (MIT, Copyright (c) 2024 Mario Zechner): + Inspired by badlogic/pi-skills (MIT, Copyright (c) 2024 Mario Zechner): https://github.com/badlogic/pi-skills/blob/main/brave-search/search.js + Modified: rewritten against the Kagi Universal Search API (v1); key read from + the OS keyring instead of an environment variable. diff --git a/README.md b/README.md index f97df6e..094ade1 100644 --- a/README.md +++ b/README.md @@ -4,117 +4,21 @@ Personal [Pi](https://pi.dev) package — extensions, skills, prompts, and theme ## Extensions -### notify - -Sends a native terminal notification (OSC 777) when Pi finishes and is waiting for input. Works in Ghostty, iTerm2, WezTerm, and rxvt-unicode. - -### handoff - -Transfers context to a new focused session. `/handoff ` summarizes the current conversation (decisions, key findings, relevant files) into a self-contained prompt, then creates a new session with the prompt as a draft in the editor for review before submitting — a lossless alternative to compaction. - -Taken from pi's handoff example (examples/extensions/handoff.ts). - -**Usage:** -```text -/handoff -``` - -### goal - -Long-running objective mode. `/goal ` sets a persistent goal for the session; after every agent turn a continuation is automatically queued, so the agent keeps working autonomously until the objective is verifiably complete, genuinely blocked, or paused. Goal state lives in the session log (surviving `/reload`, `/resume`, and tree navigation) — no external database. Time and token usage are tracked and shown in the footer, with an optional token budget that stops automatic continuation when reached. - -The agent manages the goal itself via three tools: `get_goal` (status and budgets), `create_goal` (only on explicit user request), and `update_goal` (mark `complete` after a strict verification audit, or `blocked` only after the same blocker repeats across three consecutive goal turns). - -**Usage:** -```text -/goal set and start pursuing a goal -/goal show the current goal -/goal edit edit the current objective -/goal pause pause automatic continuation -/goal resume resume a paused/blocked goal -/goal clear clear the current goal -``` - -Derived from [mitsuhiko's goal extension](https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/goal.ts). - -### tool-guidance (experimental) - -Steers file work to the dedicated tools at both places the model reads before it picks a tool. - -The built-in `bash` snippet in the prompt's tool list reads "Execute bash commands (ls, grep, find, etc.)" — it advertises precisely the three operations that `ls`, `find`, and `grep` do better, and a description at selection time beats a rule 100 lines earlier. It is replaced with the shell's actual lane (`git, npm, builds, etc.`). A routing guideline on `bash` and `powershell` then states the same thing positively — shell for git, builds, installs, pipelines; file work as its own tool call — which also covers mutating files via `edit`/`write` rather than `sed -i` or `cat >`. - -It also adds the missing preference lines for `grep`, `find`, and `ls`, the same way `read` already says "Use read to examine files instead of cat or sed". Those three built-ins ship with no guidelines, so nothing steers the model away from bash `grep`/`rg`, `find`/`fd`, and `ls` — the dedicated tools respect `.gitignore` and `grep` returns line numbers. - -Always on; no usage or flags. It patches prompt metadata via `before_agent_start` rather than re-registering the tools, so it composes with extensions that override a built-in tool's `execute`. The snippet swap is guarded on pi's exact built-in text: if upstream rewords it, the extension reports the mismatch as an extension error once per session instead of going silently out of date. - -Still experimental — a local stopgap while the equivalent one-line changes are proposed upstream. - -## Skills - -### github - -Routes GitHub work — issues, PRs, CI runs, releases, search, API queries — through the [`gh`](https://cli.github.com) CLI instead of `curl https://api.github.com/... | python3`, which is unauthenticated (60/hour versus 5000), blind to private repos, and re-implements the `--json`/`--jq` the CLI already ships. It states the few habits that change agent behaviour — explicit `--repo`, projected output, `--log-failed`, `gh api` for the gaps, confirmation before writes — and leaves the details to `gh --help`. Auto-loaded for github.com tasks, or `/skill:github`. - -See [skills/github/SKILL.md](skills/github/SKILL.md) and [skills/github/README.md](skills/github/README.md) for `gh` install/auth setup, including headless and remote hosts. - -Derived from [mitsuhiko's agent-stuff `skills/github`](https://github.com/mitsuhiko/agent-stuff/blob/main/skills/github/SKILL.md), expanded with the issue/PR/CI/search/release/API recipes above. - -### kagi - -Web search and page-content extraction via the [Kagi API](https://kagi.com/api/docs) (v1). Pure Node.js, no browser or npm dependencies. The API key is read from the OS keyring at call time — GNOME Keyring via `secret-tool`, or the macOS Keychain. - -```bash -skills/kagi/search.mjs "query" -n 5 --time week -skills/kagi/extract.mjs https://example.com/article -``` - -See [skills/kagi/SKILL.md](skills/kagi/SKILL.md) for full usage, and [skills/kagi/README.md](skills/kagi/README.md) for keyring setup and troubleshooting (including over SSH). - -### session-review - -Reviews past Pi session logs and turns them into evidence-backed improvements. `session-report.mjs` reads Pi's v3 session JSONL and prints one loose JSON object per tool call (`ts`, `session`, `project`, `tool`, `ok`, `bytes`, `msg`, plus opt-in `args`/`details`/`err`), or — with `--usage` — one object per model-attributed usage event (`kind`, `model`, `provider`, token counts, `cost`, `calls`, `stop`), which is how you trend tokens, cost, aborts, and compaction instead of hand-rolling jq over the raw log. Then you slice it with `jq` — counts, error rates, large outputs, fan-out, repeated calls, monthly cost. It does no aggregation and no domain-specific analysis, and it fails loudly with `file:line` on invalid JSON, a non-v3 header, malformed entries, or a result for an unknown call. - -Pi never prunes sessions, so the analyzer assumes a growing corpus: `--since` skips whole session files whose mtime predates the cutoff (append-only logs make mtime a sound upper bound), `--usage` streams records as they parse so memory stays flat, and `--stats` reports files read, files skipped, rows, and elapsed time. Full history is under a second either way. Explicit invocation only: run the script directly, or ask an agent via `/skill:session-review`. - -```bash -skills/session-review/session-report.mjs --since 30d -skills/session-review/session-report.mjs --since 30d --tool bash,read | jq -r .tool | sort | uniq -c -skills/session-review/session-report.mjs --since 7d --errors-only --args -skills/session-review/session-report.mjs --usage --stats # one row per billed turn -skills/session-review/session-report.mjs --since 30d --usage \ - | jq -n 'reduce inputs as $u ({}; .[$u.model // "?"] = ((.[$u.model // "?"] // 0) + ($u.total // 0))) | to_entries' -``` - -Docs are layered so an agent only pays for what the question needs: [SKILL.md](skills/session-review/SKILL.md) covers tool-call records — fields, `jq` recipes, long-history behavior, reading the raw log for prompt content, and how to interpret results — and [usage-records.md](skills/session-review/usage-records.md) holds the `--usage` schema, its recipes, and its gotchas for token/cost/model questions. Both layers, and this entry, are meant to change together. +- [goal.ts](./extensions/goal.ts) - long-running objective mode with automatic continuation. +- [handoff.ts](./extensions/handoff.ts) - transfers context to a new focused session. +- [notify.ts](./extensions/notify.ts) - sends a native terminal notification (OSC 777) when Pi finishes and is waiting for input. +- [tool-guidance.ts](./extensions/tool-guidance.ts) - steers Pi's system prompt to use dedicated tools. ## Prompts -### plan - -A lightweight discussion/planning mode for when you want to explore a problem space and narrow down an approach before any implementation. Enters a read-only thinking-partner stance: grounds the discussion in the codebase, asks only decision-relevant questions, sketches alternatives with trade-offs, and ends with a short concrete plan plus an explicit approval gate before any code is written. +- [plan](./prompts/plan.md) - lightweight discussion and planning mode for exploring a topic before doing any work. -**Usage:** -```text -/plan start exploring a specific problem -/plan ask what to explore -``` +## Skills -Other prompts live in `prompts/` — see [Pi prompts docs](https://pi.dev/docs/prompts). +- [github](./skills/github/README.md) - use the `gh` CLI when interacting with GitHub. +- [kagi](./skills/kagi/README.md) - web search and extraction via the Kagi API. +- [session-review](./skills/session-review/README.md) - review past Pi sessions for evidence-backed improvements. ## Themes -### catppuccin-frappe - -A soft, muted [Catppuccin](https://catppuccin.com) Frappé theme for the TUI, adapted from [pi-catppuccin](https://github.com/madeleineostoja/pi-catppuccin) with mauve as the accent, quiet surface/overlay chrome, and a gentle thinking gradient. - -Select it via `/settings` or: - -```json -{ - "theme": "catppuccin-frappe" -} -``` - -## Credits - -Inspired by, and partially derived from, [mitsuhiko's agent-stuff](https://github.com/mitsuhiko/agent-stuff) and pi's extension examples. Licensed under Apache-2.0; derived portions retain their original licenses — see [NOTICE](NOTICE). +- [catppuccin-frappe.json](./themes/catppuccin-frappe.json) - soft, muted Catppuccin Frappé theme for the TUI. diff --git a/extensions/goal.ts b/extensions/goal.ts index e4b38cd..51f02ee 100644 --- a/extensions/goal.ts +++ b/extensions/goal.ts @@ -19,8 +19,10 @@ * The agent can also manage the goal itself via the get_goal, create_goal, * and update_goal tools (e.g. marking the goal complete once verified). * - * Derived from mitsuhiko's goal extension - * (https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/goal.ts). + * Derived from [mitsuhiko/agent-stuff + * `extensions/goal.ts`](https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/goal.ts) + * (Apache-2.0) — session-log-backed state instead of an external database, an + * optional token budget, and a stricter completion and blocked audit. */ import { randomUUID } from "node:crypto"; diff --git a/extensions/handoff.ts b/extensions/handoff.ts index e56daca..82276fc 100644 --- a/extensions/handoff.ts +++ b/extensions/handoff.ts @@ -11,7 +11,9 @@ * * The generated prompt appears as a draft in the editor for review/editing. * - * Taken from pi's handoff example (examples/extensions/handoff.ts). + * Copied from [earendil-works/pi + * `packages/coding-agent/examples/extensions/handoff.ts`](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/examples/extensions/handoff.ts) + * (MIT, Copyright (c) earendil-works). */ import type { AgentMessage } from "@earendil-works/pi-agent-core"; diff --git a/extensions/notify.ts b/extensions/notify.ts index 957682e..10151e1 100644 --- a/extensions/notify.ts +++ b/extensions/notify.ts @@ -4,10 +4,9 @@ * Sends a native terminal notification via OSC 777 when Pi is done and * waiting for input. Works in Ghostty, iTerm2, WezTerm, and rxvt-unicode. * - * Derived from mitsuhiko's notify extension - * (https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/notify.ts), - * as also mirrored in pi's examples (examples/extensions/notify.ts) — - * simplified to OSC 777 only. + * Derived from [mitsuhiko/agent-stuff + * `extensions/notify.ts`](https://github.com/mitsuhiko/agent-stuff/blob/main/extensions/notify.ts) + * (Apache-2.0) — simplified to OSC 777 only; also mirrored in pi's examples. */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; diff --git a/skills/github/README.md b/skills/github/README.md index f5fcd5f..db01695 100644 --- a/skills/github/README.md +++ b/skills/github/README.md @@ -45,3 +45,7 @@ Install and authenticate `gh` **on the remote** whenever your commands run there - **`404` from a repository you can open in a browser** — the token is missing the `repo` scope: `gh auth refresh -s repo`. - **`API rate limit exceeded`** — check the budget with `gh api rate_limit`; something in the path is talking to `api.github.com` without credentials. - **`error: some commands require git`** — install `git`; `gh` shells out for clone, push, and branch operations. + +## Credits + +Derived from [mitsuhiko/agent-stuff `skills/github/SKILL.md`](https://github.com/mitsuhiko/agent-stuff/blob/main/skills/github/SKILL.md) (Apache-2.0) — states the auth rationale and the repo-targeting, output-projection, CI-log, `gh api`, and write-confirmation habits; defers details to `gh --help`. diff --git a/skills/kagi/README.md b/skills/kagi/README.md index a09d24d..0caabb9 100644 --- a/skills/kagi/README.md +++ b/skills/kagi/README.md @@ -11,7 +11,7 @@ Lookup coordinates are identical on both platforms: ## Store the key -The key comes from https://kagi.com/settings?p=api — here shown being read back out of 1Password. +The key comes from [Kagi API Keys](https://kagi.com/api/keys) — here shown being read back out of 1Password. ### Linux — libsecret (GNOME Keyring, KWallet) @@ -83,3 +83,7 @@ security delete-generic-password -s kagi -a api_key # macOS ## How it works `keyring.mjs` owns the platform dispatch and is read-only; `lib.mjs` calls it from `resolveApiKey()`. Setup is deliberately not something the scripts do for you. + +## Credits + +Inspired by [badlogic/pi-skills `brave-search/search.js`](https://github.com/badlogic/pi-skills/blob/main/brave-search/search.js) (MIT, Copyright (c) 2024 Mario Zechner) — same single-file CLI shape, rewritten against the Kagi Universal Search API (v1) with OS-keyring key lookup instead of an environment variable.