Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Develop independently loadable Pi extensions and supporting packages in one pnpm
- Pi loads TypeScript through jiti; extension workspaces normally need no build step.
- Keep each extension independently loadable through its own `package.json` `pi` manifest.
- The root `pi` manifest is the Git collection at `git:github.com/edheltzel/pi-extensions`. Only resources listed in the root `package.json` belong to that collection; see the root README for installation paths for other workspaces.
- Pi's Git install only installs root `package.json` dependencies. Collection extensions that import runtime npm packages (currently `diff`, `shiki`, `@shikijs/cli` for `pi-tool-pills`) must also list those deps on the collection root.
- Atlas-owned workspaces remain private until an explicit npm publishing decision removes that safeguard and adds a release changeset.
- Preserve upstream attribution, copyright, and split-license notices in package-level license files.

Expand Down Expand Up @@ -59,7 +60,7 @@ Interactive tests may run Pi in a bounded tmux session, send input, capture the
- `extensions/pi-anti-slop/AGENTS.md` - anti-authorship firewall, scanner packaging, licensing, and verification.
- `extensions/pi-better-ask-user/AGENTS.md` - decision UI, preview workflow, Herdr integration, and verification.
- `extensions/pi-better-btw/AGENTS.md` - temporary side-conversation overlay behavior and verification.
- `extensions/pi-leader-key/AGENTS.md` - Ctrl+X leader palette, model pickers, and verification.
- `extensions/pi-leader-key/AGENTS.md` - Ctrl+Q leader palette, model pickers, and verification.
- `extensions/pi-tool-pills/AGENTS.md` - tool pills, collapsed output, write/edit diffs, and verification.

## Maintaining this file
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The root Pi manifest exposes these Atlas-owned private workspaces:
- [`pi-anti-slop`](./extensions/pi-anti-slop/README.md) - substance-defect review and repair skills plus a local house-style gate
- [`pi-better-ask-user`](./extensions/pi-better-ask-user/README.md) - interactive decision UI, decision-gate skill, and optional Herdr integration
- [`pi-better-btw`](./extensions/pi-better-btw/README.md) - temporary in-memory side conversation overlay
- [`pi-leader-key`](./extensions/pi-leader-key/README.md) - Ctrl+X leader-key command palette
- [`pi-leader-key`](./extensions/pi-leader-key/README.md) - Ctrl+Q leader-key command palette
- [`pi-tool-pills`](./extensions/pi-tool-pills/README.md) - colored tool pills and Shiki diffs for built-in tools

The collection is a single Git-installable Pi package. The tutorial below explains how to install it, select its resources, develop against a local checkout, and publish updates.
Expand Down Expand Up @@ -159,16 +159,17 @@ pi remove -l ./extensions/context-commands
To add or remove resources from the Atlas Git collection:

1. Edit the root [`package.json`](./package.json) `pi.extensions` or `pi.skills` arrays.
2. If dependencies or workspace metadata changed, run `pnpm install` so [`pnpm-lock.yaml`](./pnpm-lock.yaml) stays current.
3. Run the relevant checks before sharing the change:
2. If a collection extension imports a runtime npm package, list it on the root `package.json` `dependencies` as well. Pi's Git install only installs that root manifest, not workspace `package.json` files.
3. If dependencies or workspace metadata changed, run `pnpm install` so [`pnpm-lock.yaml`](./pnpm-lock.yaml) stays current.
4. Run the relevant checks before sharing the change:

```sh
pnpm run typecheck
pnpm run test
```

4. Commit and push the repository change.
5. Update the installed Git package:
5. Commit and push the repository change.
6. Update the installed Git package:

```sh
pi update git:github.com/edheltzel/pi-extensions
Expand Down
4 changes: 3 additions & 1 deletion extensions/pi-leader-key/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## Purpose

Provide a Ctrl+X / `/lk` leader-key overlay that groups frequent Pi actions, including scoped-model and model-switcher flows.
Provide a Ctrl+Q / `/lk` leader-key overlay that groups frequent Pi actions, including scoped-model and model-switcher flows.

Do not bind `ctrl+x`: current Pi uses it for `app.message.copy` (and scoped-models `app.models.clearAll`), so the extension shortcut is skipped.

## Ownership

Expand Down
6 changes: 3 additions & 3 deletions extensions/pi-leader-key/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# pi-leader-key

Ctrl+X leader-key command palette for [pi](https://github.com/earendil-works/pi).
Ctrl+Q leader-key command palette for [pi](https://github.com/earendil-works/pi).

Press `Ctrl+X` (or run `/lk`) to open a floating palette of grouped actions, then press a chord and an action key. The palette is an Atlas-owned port of [tomsej's leader-key extension](https://github.com/tomsej/pi-ext).
Press `Ctrl+Q` (or run `/lk`) to open a floating palette of grouped actions, then press a chord and an action key. Pi already binds `Ctrl+X` to copy the last assistant message, so this extension does not register that shortcut. The palette is an Atlas-owned port of [tomsej's leader-key extension](https://github.com/tomsej/pi-ext).

## Install

Expand All @@ -28,7 +28,7 @@ This workspace remains private and is not published to npm. Run `/reload` after

## Usage

- `Ctrl+X` or `/lk` opens the leader palette
- `Ctrl+Q` or `/lk` opens the leader palette
- `Ctrl+M` opens the scoped-models picker directly
- Chord keys open a group; a letter key runs an action
- `Esc` / `Backspace` goes back or closes
Expand Down
2 changes: 1 addition & 1 deletion extensions/pi-leader-key/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@edheltzel/pi-leader-key",
"version": "0.1.0",
"private": true,
"description": "Ctrl+X leader-key command palette for Pi",
"description": "Ctrl+Q leader-key command palette for Pi",
"keywords": [
"extension",
"leader-key",
Expand Down
4 changes: 2 additions & 2 deletions extensions/pi-leader-key/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Leader Key Extension
*
* Press Ctrl+X to open a floating command palette showing available
* Press Ctrl+Q to open a floating command palette showing available
* actions organised into groups (like Vim's which-key or Emacs' leader key).
*
* Ported from tomsej/pi-ext leader-key (MIT).
Expand Down Expand Up @@ -350,7 +350,7 @@ export default function leaderKeyExtension(pi: ExtensionAPI) {
},
});

pi.registerShortcut(Key.ctrl("x"), {
pi.registerShortcut(Key.ctrl("q"), {
description: "Open Leader Key",
handler: async (ctx) => {
await openLeaderKey(ctx);
Expand Down
48 changes: 44 additions & 4 deletions extensions/pi-leader-key/tests/overlay.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,54 @@
import { describe, expect, it } from "vitest";
import type { Theme } from "@earendil-works/pi-coding-agent";
import { visibleWidth } from "@earendil-works/pi-tui";
import { buildEntries, LeaderKeyOverlay } from "../src/index";
import { describe, expect, it, vi } from "vitest";
import type { ExtensionAPI, ExtensionContext, Theme } from "@earendil-works/pi-coding-agent";
import { Key, visibleWidth } from "@earendil-works/pi-tui";
import leaderKeyExtension, { buildEntries, LeaderKeyOverlay } from "../src/index";
import { OverlayFrame, padToWidth } from "../src/overlay";

const theme = {
fg: (_color: string, text: string) => text,
bold: (text: string) => text,
} as unknown as Theme;

describe("extension registration", () => {
it("opens the palette from Ctrl+Q and /lk without registering Ctrl+X", async () => {
type Shortcut = { handler: (ctx: ExtensionContext) => Promise<void> };
type Command = { handler: (args: string, ctx: ExtensionContext) => Promise<void> };

const shortcuts = new Map<string, Shortcut>();
const commands = new Map<string, Command>();
const pi = {
on: vi.fn(),
registerShortcut: vi.fn((key: string, shortcut: Shortcut) => {
shortcuts.set(key, shortcut);
}),
registerCommand: vi.fn((name: string, command: Command) => {
commands.set(name, command);
}),
} as unknown as ExtensionAPI;

leaderKeyExtension(pi);

expect([...shortcuts.keys()]).toEqual([Key.ctrl("q")]);
expect(shortcuts.has(Key.ctrl("x"))).toBe(false);
expect([...commands.keys()]).toContain("lk");

const shortcut = shortcuts.get(Key.ctrl("q"));
const command = commands.get("lk");
if (!shortcut || !command) throw new Error("Leader key triggers were not registered");

const custom = vi.fn(async () => null);
const ctx = { hasUI: true, ui: { custom } } as unknown as ExtensionContext;
await shortcut.handler(ctx);
await command.handler("", ctx);

expect(custom).toHaveBeenCalledTimes(2);
expect(custom.mock.calls[0]?.[1]).toMatchObject({
overlay: true,
overlayOptions: { anchor: "center", width: 80 },
});
});
});

describe("OverlayFrame", () => {
it("pads content to a visible width", () => {
expect(padToWidth("hi", 4)).toBe("hi ");
Expand Down
5 changes: 4 additions & 1 deletion knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@
"@earendil-works/pi-ai",
"@earendil-works/pi-coding-agent",
"@earendil-works/pi-tui",
"@sinclair/typebox"
"@sinclair/typebox",
"@shikijs/cli",
"diff",
"shiki"
],
"ignoreIssues": {
"extensions/preset/src/extension.ts": ["duplicates"]
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"typecheck": "tsc --noEmit -p tsconfig.json",
"changeset-publish": "changeset publish"
},
"dependencies": {
"@shikijs/cli": "^3.15.0",
"diff": "^8.0.2",
"shiki": "^3.15.0"
},
"devDependencies": {
"@changesets/changelog-github": "=0.6.0",
"@changesets/cli": "=2.31.0",
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading