@counterposition/skill-pi 0.1.1 → 0.2.0

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.
@@ -1,97 +1,127 @@
1
1
  # Pi Packages
2
2
 
3
- Packages bundle extensions, skills, prompt templates, and themes for sharing via npm, git, or local paths.
3
+ Pi packages bundle extensions, skills, prompt templates, and themes so they can be shared through npm, git, or local paths.
4
4
 
5
- **Security warning:** Packages run with full system access. Extensions execute arbitrary code, skills can instruct the model to perform any action. Review source before installing third-party packages.
5
+ **Security warning:** Pi packages run with full system access. Review third-party source before installing it.
6
6
 
7
- ## Installation
7
+ ## Install and Manage
8
8
 
9
9
  ```bash
10
- # From npm
11
- pi install npm:@foo/pi-extensions@1.0.0
12
-
13
- # From git
10
+ pi install npm:@foo/bar@1.0.0
14
11
  pi install git:github.com/user/repo@v1
15
- pi install https://github.com/user/repo.git
16
- pi install git@github.com:user/repo.git
17
-
18
- # From local path
19
- pi install ./my-package
12
+ pi install https://github.com/user/repo
20
13
  pi install /absolute/path/to/package
14
+ pi install ./relative/path/to/package
21
15
 
22
- # Project-local install (writes to .pi/settings.json for team sharing)
23
- pi install -l npm:@foo/pi-extensions
24
-
25
- # Temporary trial (loads for current session, doesn't install)
26
- pi -e npm:@foo/pi-extensions
16
+ pi remove npm:@foo/bar
17
+ pi uninstall npm:@foo/bar
18
+ pi list
19
+ pi update
20
+ pi config
27
21
  ```
28
22
 
29
- ## Management Commands
23
+ By default, `install` and `remove` write to global settings (`~/.pi/agent/settings.json`). Use `-l` to write to project settings (`.pi/settings.json`) instead.
30
24
 
31
- ```bash
32
- pi list # List installed packages
33
- pi update # Update non-pinned packages
34
- pi remove <pkg> # Remove a package
35
- ```
25
+ Project installs are shareable with a team. Pi will install missing project packages automatically on startup.
36
26
 
37
- ## Package Structure
27
+ For temporary one-run testing, use `--extension` / `-e` with an npm or git source. Pi installs it into a temporary directory for that run only.
28
+
29
+ ## Package Sources
30
+
31
+ ### npm
32
+
33
+ ```text
34
+ npm:@scope/pkg@1.2.3
35
+ npm:pkg
36
+ ```
38
37
 
39
- ### Convention-Based (Auto-Discovery)
38
+ - Global installs use `npm install -g`
39
+ - Project installs go under `.pi/npm/`
40
+ - Version-pinned installs are skipped by `pi update`
41
+ - Use `npmCommand` in settings if you need a wrapper such as `mise` or `asdf`
40
42
 
41
- Place files in standard directories — Pi discovers them automatically:
43
+ ### git
42
44
 
43
45
  ```text
44
- my-pi-package/
45
- ├── package.json # npm package metadata + optional pi manifest
46
- ├── extensions/ # .ts and .js files → loaded as extensions
47
- │ └── my-ext.ts
48
- ├── skills/ # Directories with SKILL.md → loaded as skills
49
- │ └── my-skill/
50
- │ └── SKILL.md
51
- ├── prompts/ # .md files → loaded as prompt templates
52
- │ └── review.md
53
- └── themes/ # .json files → loaded as themes
54
- └── my-theme.json
46
+ git:github.com/user/repo@v1
47
+ git:git@github.com:user/repo@v1
48
+ https://github.com/user/repo@v1
49
+ ssh://git@github.com/user/repo@v1
55
50
  ```
56
51
 
57
- ### Manifest-Based (Explicit)
52
+ - Global clones live in `~/.pi/agent/git/`
53
+ - Project clones live in `.pi/git/`
54
+ - Refs pin the package and are skipped by `pi update`
55
+ - Pi runs `npm install` after clone/pull when `package.json` exists
58
56
 
59
- Declare resources in `package.json` under the `pi` key:
57
+ ### local paths
58
+
59
+ - Files are treated as single extensions
60
+ - Directories are loaded using normal package rules
61
+ - Relative paths resolve relative to the settings file they appear in
62
+
63
+ ## Creating a Package
64
+
65
+ Pi supports either a `pi` manifest in `package.json` or convention-based directories.
60
66
 
61
67
  ```json
62
68
  {
63
- "name": "@foo/pi-extensions",
64
- "version": "1.0.0",
69
+ "name": "my-package",
70
+ "keywords": ["pi-package"],
65
71
  "pi": {
66
- "extensions": ["src/ext1.ts", "src/ext2.ts"],
67
- "skills": ["skills/my-skill"],
68
- "prompts": ["prompts/"],
69
- "themes": ["themes/custom.json"]
72
+ "extensions": ["./extensions"],
73
+ "skills": ["./skills"],
74
+ "prompts": ["./prompts"],
75
+ "themes": ["./themes"]
70
76
  }
71
77
  }
72
78
  ```
73
79
 
74
- Both approaches can be combined. Explicit paths in the `pi` manifest take precedence.
80
+ If there is no `pi` manifest, Pi auto-discovers:
81
+
82
+ - `extensions/` for `.ts` / `.js`
83
+ - `skills/` for `SKILL.md` directories and top-level `.md` skill files
84
+ - `prompts/` for `.md`
85
+ - `themes/` for `.json`
75
86
 
76
87
  ## Dependencies
77
88
 
78
- - **Standard npm dependencies:** Declare in `package.json` → `dependencies` as usual. They're installed with the package.
79
- - **Pi peer dependencies** (`@mariozechner/pi-coding-agent`, `@mariozechner/pi-ai`, etc.): Use `"*"` as the version range in `peerDependencies`. Do NOT bundle these.
80
- - **Other Pi packages:** If your package depends on another Pi package, it must be bundled explicitly.
89
+ - Normal runtime dependencies belong in `dependencies`
90
+ - Pi core libraries should be peer deps with `"*"` ranges:
91
+ - `@mariozechner/pi-ai`
92
+ - `@mariozechner/pi-agent-core`
93
+ - `@mariozechner/pi-coding-agent`
94
+ - `@mariozechner/pi-tui`
95
+ - `@sinclair/typebox`
96
+ - Other Pi packages must be bundled explicitly if your package depends on them
81
97
 
82
- ## Publishing to npm
98
+ ## Package Filtering
83
99
 
84
- ```bash
85
- cd my-pi-package
86
- npm publish
100
+ `settings.json` can narrow package resources with object-form entries:
101
+
102
+ ```json
103
+ {
104
+ "packages": [
105
+ {
106
+ "source": "npm:my-package",
107
+ "extensions": ["extensions/*.ts", "!extensions/legacy.ts"],
108
+ "skills": [],
109
+ "prompts": ["prompts/review.md"],
110
+ "themes": ["+themes/legacy.json"]
111
+ }
112
+ ]
113
+ }
87
114
  ```
88
115
 
89
- Users install with `pi install npm:@foo/pi-extensions`.
116
+ Rules:
90
117
 
91
- ## Deduplication
118
+ - Omit a key to load all resources of that type
119
+ - Use `[]` to load none
120
+ - Use `!pattern` to exclude glob matches
121
+ - Use `+path` / `-path` for exact include or exclude
92
122
 
93
- When the same resource name appears from multiple sources:
123
+ ## Scope and Deduplication
94
124
 
95
- - Project-level packages override global ones
96
- - First discovery wins for same-level conflicts
97
- - Pi warns about collisions
125
+ - Project settings override global settings for the same package identity
126
+ - Identity is package name for npm, repo URL for git, and resolved absolute path for local sources
127
+ - `pi config` can enable or disable package resources after installation
@@ -254,16 +254,16 @@ All components implement `render(width) → string[]` and optional `handleInput(
254
254
 
255
255
  ```typescript
256
256
  // Footer status text
257
- ctx.ui.setStatus("🔍 Searching...");
257
+ ctx.ui.setStatus("search", "Searching...");
258
258
 
259
259
  // Widget above the editor
260
- ctx.ui.setWidget("above", new Text("Current task: refactoring auth", 0, 0));
260
+ ctx.ui.setWidget("current-task", new Text("Current task: refactoring auth", 0, 0));
261
261
 
262
262
  // Widget below the editor
263
- ctx.ui.setWidget("below", progressComponent);
263
+ ctx.ui.setWidget("progress", progressComponent, { placement: "belowEditor" });
264
264
 
265
265
  // Custom footer
266
- ctx.ui.setFooter(new Text(theme.fg("accent", "My Extension v1.0"), 0, 0));
266
+ ctx.ui.setFooter((tui, theme) => new Text(theme.fg("accent", "My Extension v1.0"), 0, 0));
267
267
  ```
268
268
 
269
269
  ## File Watcher / Trigger
@@ -1,71 +1,104 @@
1
1
  # Providers & Custom Models
2
2
 
3
- Pi supports 20+ LLM providers out of the box and allows adding custom providers via `models.json` or extensions.
3
+ Pi supports subscription-based providers via OAuth, API-key providers via env vars or `auth.json`, and custom providers via `models.json` or extensions.
4
4
 
5
- ## Built-in Providers
5
+ ## Subscription Providers
6
6
 
7
- ### Subscription-based (OAuth via `/login`)
7
+ Use `/login` in interactive mode, then select a provider:
8
8
 
9
- | Provider | Subscription |
10
- |----------|-------------|
11
- | Anthropic | Claude Pro / Max |
12
- | OpenAI | ChatGPT Plus / Pro |
13
- | GitHub Copilot | Copilot subscription |
14
- | Google | Google AI / Vertex |
9
+ - Anthropic Claude Pro / Max
10
+ - OpenAI ChatGPT Plus / Pro (Codex)
11
+ - GitHub Copilot
12
+ - Google Gemini CLI
13
+ - Google Antigravity
15
14
 
16
- ### API Key Providers
15
+ Use `/logout` to clear stored OAuth credentials.
17
16
 
18
- | Provider | Env Variable | Auth.json Key |
19
- |----------|-------------|---------------|
17
+ ## API Key Providers
18
+
19
+ | Provider | Env Var | `auth.json` key |
20
+ |----------|---------|-----------------|
20
21
  | Anthropic | `ANTHROPIC_API_KEY` | `anthropic` |
22
+ | Azure OpenAI Responses | `AZURE_OPENAI_API_KEY` | `azure-openai-responses` |
21
23
  | OpenAI | `OPENAI_API_KEY` | `openai` |
22
- | Google | `GOOGLE_API_KEY` | `google` |
23
- | xAI | `XAI_API_KEY` | `xai` |
24
+ | Google Gemini | `GEMINI_API_KEY` | `google` |
25
+ | Mistral | `MISTRAL_API_KEY` | `mistral` |
24
26
  | Groq | `GROQ_API_KEY` | `groq` |
25
27
  | Cerebras | `CEREBRAS_API_KEY` | `cerebras` |
28
+ | xAI | `XAI_API_KEY` | `xai` |
26
29
  | OpenRouter | `OPENROUTER_API_KEY` | `openrouter` |
27
- | Mistral | `MISTRAL_API_KEY` | `mistral` |
30
+ | Vercel AI Gateway | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway` |
31
+ | ZAI | `ZAI_API_KEY` | `zai` |
32
+ | OpenCode Zen | `OPENCODE_API_KEY` | `opencode` |
33
+ | OpenCode Go | `OPENCODE_API_KEY` | `opencode-go` |
28
34
  | Hugging Face | `HF_TOKEN` | `huggingface` |
35
+ | Kimi For Coding | `KIMI_API_KEY` | `kimi-coding` |
29
36
  | MiniMax | `MINIMAX_API_KEY` | `minimax` |
30
- | Together | `TOGETHER_API_KEY` | `together` |
31
- | Fireworks | `FIREWORKS_API_KEY` | `fireworks` |
32
- | DeepSeek | `DEEPSEEK_API_KEY` | `deepseek` |
33
- | Sambanova | `SAMBANOVA_API_KEY` | `sambanova` |
34
-
35
- ## Credential Priority
36
-
37
- 1. CLI flags (`--api-key`)
38
- 2. `~/.pi/agent/auth.json` entries
39
- 3. Environment variables
40
- 4. Custom provider config in `models.json`
37
+ | MiniMax (China) | `MINIMAX_CN_API_KEY` | `minimax-cn` |
41
38
 
42
- ## Auth File Format
39
+ ## Auth File
43
40
 
44
- `~/.pi/agent/auth.json` (permissions: `0600`):
41
+ `~/.pi/agent/auth.json` stores API keys and OAuth tokens with `0600` permissions:
45
42
 
46
43
  ```json
47
44
  {
48
- "anthropic": {
49
- "key": "sk-ant-..."
50
- },
51
- "openai": {
52
- "key": "!op read 'OpenAI API Key'"
53
- },
54
- "google": {
55
- "key": "GOOGLE_API_KEY"
56
- }
45
+ "anthropic": { "type": "api_key", "key": "sk-ant-..." },
46
+ "openai": { "type": "api_key", "key": "!op read 'OpenAI API Key'" },
47
+ "google": { "type": "api_key", "key": "GEMINI_API_KEY" }
57
48
  }
58
49
  ```
59
50
 
60
- Key value resolution:
51
+ `key` values can be:
52
+
53
+ - A literal secret
54
+ - An environment variable name
55
+ - A shell command prefixed with `!`
56
+
57
+ ## Credential Resolution Order
58
+
59
+ 1. `--api-key`
60
+ 2. `auth.json`
61
+ 3. Environment variables
62
+ 4. Custom provider keys from `models.json`
63
+
64
+ ## Cloud Providers
65
+
66
+ ### Azure OpenAI
67
+
68
+ ```bash
69
+ export AZURE_OPENAI_API_KEY=...
70
+ export AZURE_OPENAI_BASE_URL=https://your-resource.openai.azure.com
71
+ export AZURE_OPENAI_API_VERSION=2024-02-01
72
+ export AZURE_OPENAI_DEPLOYMENT_NAME_MAP=gpt-4o=my-gpt4o
73
+ ```
74
+
75
+ ### Amazon Bedrock
76
+
77
+ Pi supports standard AWS auth flows:
61
78
 
62
- - **Literal:** `"sk-ant-..."` — used directly
63
- - **Shell command:** `"!command"` — executes command, uses stdout
64
- - **Env variable:** `"ENV_VAR_NAME"` — reads from environment
79
+ - `AWS_PROFILE`
80
+ - `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY`
81
+ - `AWS_BEARER_TOKEN_BEDROCK`
82
+
83
+ Useful extras:
84
+
85
+ - `AWS_REGION`
86
+ - `AWS_BEDROCK_FORCE_CACHE=1` for application inference profiles
87
+ - `AWS_ENDPOINT_URL_BEDROCK_RUNTIME` / `AWS_BEDROCK_SKIP_AUTH` / `AWS_BEDROCK_FORCE_HTTP1` for proxies
88
+
89
+ ### Google Vertex AI
90
+
91
+ Use ADC:
92
+
93
+ ```bash
94
+ gcloud auth application-default login
95
+ export GOOGLE_CLOUD_PROJECT=your-project
96
+ export GOOGLE_CLOUD_LOCATION=us-central1
97
+ ```
65
98
 
66
- ## Custom Models via models.json
99
+ ## Custom Providers via `models.json`
67
100
 
68
- `~/.pi/agent/models.json`:
101
+ Use `models.json` for OpenAI-compatible, Anthropic-compatible, Google-compatible, or other supported APIs:
69
102
 
70
103
  ```json
71
104
  {
@@ -81,8 +114,7 @@ Key value resolution:
81
114
  "name": "Llama 3.2",
82
115
  "contextWindow": 128000,
83
116
  "maxTokens": 4096,
84
- "input": ["text"],
85
- "reasoning": false
117
+ "input": ["text"]
86
118
  }
87
119
  ]
88
120
  }
@@ -90,123 +122,39 @@ Key value resolution:
90
122
  }
91
123
  ```
92
124
 
93
- ### Supported API Types
94
-
95
- | API | Value |
96
- |-----|-------|
97
- | OpenAI Chat Completions | `"openai-completions"` |
98
- | OpenAI Responses | `"openai-responses"` |
99
- | Anthropic Messages | `"anthropic-messages"` |
100
- | Google Generative AI | `"google-generative-ai"` |
101
- | Google Vertex AI | `"google-vertex"` |
102
- | Azure OpenAI | `"azure-openai-responses"` |
103
- | Mistral | `"mistral-conversations"` |
104
- | Amazon Bedrock | `"bedrock-converse-stream"` |
105
-
106
- ### Model Fields
107
-
108
- | Field | Required | Type | Description |
109
- |-------|----------|------|-------------|
110
- | `id` | Yes | string | Model ID sent to API |
111
- | `name` | No | string | Human-readable display name |
112
- | `reasoning` | No | boolean | Supports extended thinking |
113
- | `input` | No | string[] | `["text"]` or `["text", "image"]` |
114
- | `contextWindow` | No | number | Max context tokens |
115
- | `maxTokens` | No | number | Max output tokens |
116
- | `cost` | No | object | `{ input, output, cacheRead, cacheWrite }` per million tokens |
117
-
118
- ### Provider Fields
119
-
120
- | Field | Required | Description |
121
- |-------|----------|-------------|
122
- | `name` | Yes | Provider identifier |
123
- | `baseUrl` | Yes | API endpoint URL |
124
- | `api` | Yes | API type (see table above) |
125
- | `apiKey` | Yes | API key (literal, env var, or shell command) |
126
- | `models` | Yes | Array of model definitions |
127
- | `headers` | No | Custom HTTP headers (same value resolution as apiKey) |
128
-
129
- ### Compatibility Settings
130
-
131
- For partially OpenAI-compatible APIs, use the `compat` field on models:
125
+ Common `api` values:
132
126
 
133
- ```json
134
- {
135
- "compat": {
136
- "supportsDeveloperRole": false,
137
- "supportsReasoningEffort": false,
138
- "supportsStreamOptions": true,
139
- "openRouterProviderOrder": ["anthropic", "google"]
140
- }
141
- }
142
- ```
127
+ - `"openai-completions"`
128
+ - `"openai-responses"`
129
+ - `"anthropic-messages"`
130
+ - `"google-generative-ai"`
131
+ - `"google-vertex"`
132
+ - `"azure-openai-responses"`
133
+ - `"mistral-conversations"`
134
+ - `"bedrock-converse-stream"`
143
135
 
144
- ## Cloud Providers
136
+ ## Custom Providers via Extensions
145
137
 
146
- ### Azure OpenAI
138
+ Use extensions when you need custom streaming, custom headers, or OAuth/device-flow logic:
147
139
 
148
- ```json
149
- {
150
- "name": "azure-openai",
151
- "baseUrl": "https://myresource.openai.azure.com",
152
- "api": "azure-openai-responses",
153
- "apiKey": "AZURE_OPENAI_API_KEY",
154
- "models": [{ "id": "gpt-4o", "name": "GPT-4o" }]
155
- }
140
+ ```typescript
141
+ pi.registerProvider("my-provider", {
142
+ baseUrl: "https://api.example.com",
143
+ api: "openai-completions",
144
+ apiKey: "MY_PROVIDER_KEY",
145
+ models: [{ id: "my-model", name: "My Model", contextWindow: 128000, maxTokens: 4096 }],
146
+ });
156
147
  ```
157
148
 
158
- ### Amazon Bedrock
159
-
160
- Uses AWS credentials (profile, IAM keys, or bearer tokens). Set `AWS_PROFILE` or `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`. Pi auto-enables Bedrock for Claude models when credentials are available.
161
-
162
- ### Google Vertex AI
149
+ ## SDK / Extension Auth Lookup
163
150
 
164
- Uses Application Default Credentials: `gcloud auth application-default login`.
165
-
166
- ## Custom Provider via Extension
167
-
168
- For full control (custom streaming, OAuth, etc.):
151
+ If extension or SDK code needs auth for a specific model request, use `getApiKeyAndHeaders(model)` rather than the removed `getApiKey(model)`:
169
152
 
170
153
  ```typescript
171
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
172
-
173
- export default function (pi: ExtensionAPI) {
174
- pi.registerProvider("my-provider", {
175
- baseUrl: "https://api.example.com",
176
- api: "openai-completions",
177
- apiKey: "my-key",
178
- models: [
179
- { id: "my-model", name: "My Model", contextWindow: 128000, maxTokens: 4096 }
180
- ],
181
- // Optional: custom streaming for non-standard APIs
182
- streamSimple: async (model, context, options) => {
183
- // Return AsyncIterable<AssistantMessageEvent>
184
- },
185
- // Optional: OAuth device flow
186
- oauth: {
187
- deviceCodeUrl: "https://auth.example.com/device",
188
- tokenUrl: "https://auth.example.com/token",
189
- clientId: "my-client-id",
190
- scopes: ["chat"],
191
- },
192
- });
193
- }
194
- ```
154
+ const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
155
+ if (!auth.ok) throw new Error(auth.error);
195
156
 
196
- ## Overriding Built-in Providers
197
-
198
- To route a built-in provider through a proxy while keeping its models:
199
-
200
- ```json
201
- {
202
- "providers": [
203
- {
204
- "name": "anthropic",
205
- "baseUrl": "https://my-proxy.example.com/v1",
206
- "apiKey": "proxy-key"
207
- }
208
- ]
209
- }
157
+ const { apiKey, headers } = auth;
210
158
  ```
211
159
 
212
- Models.json reloads automatically when accessing `/model` — no restart needed.
160
+ This matters for providers whose headers or auth values resolve dynamically on every request.