@zgltyq/pi-provider-claude 1.0.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.
- package/LICENSE +23 -0
- package/README.md +92 -0
- package/index.ts +283 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Leechael
|
|
4
|
+
|
|
5
|
+
Based on @benvargas/pi-claude-code-use (MIT License, Copyright (c) Ben Vargas).
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @zgltyq/pi-provider-claude
|
|
2
|
+
|
|
3
|
+
Claude (Anthropic **OAuth / subscription**) compatibility layer for
|
|
4
|
+
[pi-coding-agent](https://pi.dev). Keeps **all** your extension tools usable
|
|
5
|
+
under the Claude subscription.
|
|
6
|
+
|
|
7
|
+
It is a self-contained fork of the tool-handling half of
|
|
8
|
+
[`@benvargas/pi-claude-code-use`](https://www.npmjs.com/package/@benvargas/pi-claude-code-use)
|
|
9
|
+
(MIT) — credit to Ben Vargas for the original approach.
|
|
10
|
+
|
|
11
|
+
## Problem
|
|
12
|
+
|
|
13
|
+
Anthropic's OAuth (subscription) request path appears to fingerprint tool names.
|
|
14
|
+
Tools that are **not** part of the Claude Code core set and are **not** prefixed
|
|
15
|
+
`mcp__` can be classified as *extra usage*. The upstream extension defends against
|
|
16
|
+
this by **dropping every unknown flat-named tool** before the request is sent —
|
|
17
|
+
which silently hides legitimate extension tools from Claude:
|
|
18
|
+
|
|
19
|
+
`ask_user_question`, `todo`, `subagent`, `ast_grep_search`, `lsp_diagnostics`,
|
|
20
|
+
`ctx_*`, `web_search`, `ralph_*`, `preview_export`, … all disappear, even though
|
|
21
|
+
they work fine for non-Anthropic models.
|
|
22
|
+
|
|
23
|
+
## What this does
|
|
24
|
+
|
|
25
|
+
Instead of dropping unknown flat tools, it **renames them in place on the wire**
|
|
26
|
+
to `mcp__pi__<name>`:
|
|
27
|
+
|
|
28
|
+
- ✅ `mcp__*` shape passes Anthropic's classifier → **no extra-usage charge**
|
|
29
|
+
- ✅ the tool stays **visible to Claude** → it can actually call it
|
|
30
|
+
- ✅ on the way back, calls to `mcp__pi__*` are rewritten to the original flat
|
|
31
|
+
name **before Pi executes them**, so the real tool (and its closure-bound
|
|
32
|
+
state) runs unchanged
|
|
33
|
+
|
|
34
|
+
Untouched: native Anthropic tools (objects with a `type` field, e.g.
|
|
35
|
+
`web_search`), anything already `mcp__`-prefixed, and the Claude Code core tools.
|
|
36
|
+
The extension only activates for **Anthropic + OAuth** — API-key auth and
|
|
37
|
+
non-Anthropic providers pass through completely unchanged.
|
|
38
|
+
|
|
39
|
+
It also applies the upstream system-prompt rewrite (`pi itself` → `the cli
|
|
40
|
+
itself`, etc.) on the OAuth path.
|
|
41
|
+
|
|
42
|
+
## Why it's lightweight
|
|
43
|
+
|
|
44
|
+
The tool's full JSON schema already rides inside the outbound payload, so the fix
|
|
45
|
+
is a pure rename — **no jiti capture, no tool re-registration, no typebox**. The
|
|
46
|
+
only import is a TypeScript type (erased at runtime), so the extension has **zero
|
|
47
|
+
runtime dependencies**.
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pi install npm:@zgltyq/pi-provider-claude
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Then remove the upstream one so they don't both transform the payload:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pi remove npm:@benvargas/pi-claude-code-use
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Restart Pi (or `/reload`) and continue using the normal `anthropic` provider with
|
|
62
|
+
your OAuth login.
|
|
63
|
+
|
|
64
|
+
## Verify
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
PI_CLAUDE_PROVIDER_DEBUG_LOG=/tmp/claude-provider.log pi
|
|
68
|
+
# send one message, then quit
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
In `/tmp/claude-provider.log`, the `"after"` payload's `tools[]` should show your
|
|
72
|
+
extension tools as `mcp__pi__<name>` and **nothing dropped**.
|
|
73
|
+
|
|
74
|
+
## Environment variables
|
|
75
|
+
|
|
76
|
+
| Variable | Effect |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `PI_CLAUDE_PROVIDER_DEBUG_LOG=/path` | Append `before`/`after` payloads for debugging. |
|
|
79
|
+
| `PI_CLAUDE_PROVIDER_DISABLE=1` | Pass all tools through with flat names (no renaming). Debug escape hatch. |
|
|
80
|
+
|
|
81
|
+
## How it differs from `@benvargas/pi-claude-code-use`
|
|
82
|
+
|
|
83
|
+
| | upstream | this fork |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| Unknown flat tools | **dropped** | **renamed** `mcp__pi__<name>` (kept) |
|
|
86
|
+
| Alias scheme | per-tool config + jiti capture + re-registration | generic in-place rename (deterministic prefix) |
|
|
87
|
+
| Runtime deps | `@mariozechner/jiti` | none |
|
|
88
|
+
| Scope | tool filtering + companion aliases + system-prompt rewrite | tool renaming + system-prompt rewrite |
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT. Based on `@benvargas/pi-claude-code-use` (MIT).
|
package/index.ts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zgltyq/pi-provider-claude
|
|
3
|
+
* ────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
* Claude (Anthropic OAuth / subscription) compatibility layer for pi-coding-agent.
|
|
5
|
+
* Self-contained fork of the tool-handling half of `@benvargas/pi-claude-code-use`
|
|
6
|
+
* (MIT). Credit to Ben Vargas for the original approach.
|
|
7
|
+
*
|
|
8
|
+
* WHY THIS EXISTS
|
|
9
|
+
* Anthropic's OAuth (subscription) request path appears to fingerprint tool
|
|
10
|
+
* names: tools that are neither part of the Claude Code core set nor prefixed
|
|
11
|
+
* `mcp__` can be classified as "extra usage". The upstream extension defends
|
|
12
|
+
* against this by DROPPING every unknown flat-named tool — which silently
|
|
13
|
+
* hides legitimate extension tools (ask_user_question, todo, subagent,
|
|
14
|
+
* ast_grep_search, ctx_*, web_search, …) from Claude.
|
|
15
|
+
*
|
|
16
|
+
* WHAT THIS DOES DIFFERENTLY (the "map all my tools" fix)
|
|
17
|
+
* Instead of dropping unknown flat tools, it RENAMES them in place on the
|
|
18
|
+
* wire to `mcp__pi__<name>` so they pass the classifier (subscription-safe)
|
|
19
|
+
* AND remain visible to Claude. On the way back, tool calls to `mcp__pi__*`
|
|
20
|
+
* are rewritten to their original flat name before Pi executes them, so the
|
|
21
|
+
* real tool (and its closure-bound state) runs unchanged.
|
|
22
|
+
*
|
|
23
|
+
* DESIGN NOTES
|
|
24
|
+
* - The tool's full JSON schema already rides inside the outbound payload,
|
|
25
|
+
* so we just rename — NO jiti capture, NO tool re-registration, NO typebox.
|
|
26
|
+
* The only import is a TYPE (erased at runtime), so this extension has zero
|
|
27
|
+
* runtime dependencies and minimal chance of a load failure.
|
|
28
|
+
* - Native Anthropic tools (objects with a `type` field, e.g. web_search) and
|
|
29
|
+
* anything already `mcp__`-prefixed are passed through untouched. Core
|
|
30
|
+
* Claude Code tools are passed through untouched.
|
|
31
|
+
* - Only ACTIVATES for Anthropic + OAuth. API-key and non-Anthropic providers
|
|
32
|
+
* are left completely unchanged.
|
|
33
|
+
*
|
|
34
|
+
* ENV (optional)
|
|
35
|
+
* PI_CLAUDE_PROVIDER_DEBUG_LOG=/path → append before/after payloads
|
|
36
|
+
* PI_CLAUDE_PROVIDER_DISABLE=1 → pass everything through flat (debug)
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
import { appendFileSync } from "node:fs";
|
|
40
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
41
|
+
|
|
42
|
+
// Prefix used to disguise flat tools as MCP tools. Kept short so
|
|
43
|
+
// `mcp__pi__<name>` stays well under Anthropic's 64-char tool-name limit.
|
|
44
|
+
const ALIAS_PREFIX = "mcp__pi__";
|
|
45
|
+
|
|
46
|
+
// Core Claude Code tool names that always pass through (lowercased).
|
|
47
|
+
// Mirrors Pi core's `claudeCodeTools` in packages/ai/src/providers/anthropic.ts.
|
|
48
|
+
const CORE_TOOL_NAMES = new Set([
|
|
49
|
+
"read",
|
|
50
|
+
"write",
|
|
51
|
+
"edit",
|
|
52
|
+
"bash",
|
|
53
|
+
"grep",
|
|
54
|
+
"glob",
|
|
55
|
+
"askuserquestion",
|
|
56
|
+
"enterplanmode",
|
|
57
|
+
"exitplanmode",
|
|
58
|
+
"killshell",
|
|
59
|
+
"notebookedit",
|
|
60
|
+
"skill",
|
|
61
|
+
"task",
|
|
62
|
+
"taskoutput",
|
|
63
|
+
"todowrite",
|
|
64
|
+
"webfetch",
|
|
65
|
+
"websearch",
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
const lower = (s: string): string => s.toLowerCase();
|
|
69
|
+
const isPlainObject = (v: unknown): v is Record<string, unknown> =>
|
|
70
|
+
typeof v === "object" && v !== null && !Array.isArray(v);
|
|
71
|
+
|
|
72
|
+
// ─── System prompt rewrite (parity with upstream) ────────────────────────────
|
|
73
|
+
// Keep Pi's identity out of the system prompt on the OAuth path.
|
|
74
|
+
function rewritePromptText(text: string): string {
|
|
75
|
+
return text
|
|
76
|
+
.replaceAll("pi itself", "the cli itself")
|
|
77
|
+
.replaceAll("pi .md files", "cli .md files")
|
|
78
|
+
.replaceAll("pi packages", "cli packages");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function rewriteSystemField(system: unknown): unknown {
|
|
82
|
+
if (typeof system === "string") return rewritePromptText(system);
|
|
83
|
+
if (!Array.isArray(system)) return system;
|
|
84
|
+
return system.map((block) => {
|
|
85
|
+
if (
|
|
86
|
+
!isPlainObject(block) ||
|
|
87
|
+
block.type !== "text" ||
|
|
88
|
+
typeof block.text !== "string"
|
|
89
|
+
)
|
|
90
|
+
return block;
|
|
91
|
+
const rewritten = rewritePromptText(block.text);
|
|
92
|
+
return rewritten === block.text ? block : { ...block, text: rewritten };
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// True for tools that must NOT be renamed: native typed tools, core tools,
|
|
97
|
+
// already-mcp__ tools, or nameless entries.
|
|
98
|
+
function shouldRename(tool: Record<string, unknown>): boolean {
|
|
99
|
+
if (typeof tool.type === "string" && tool.type.trim().length > 0)
|
|
100
|
+
return false; // native (web_search, …)
|
|
101
|
+
const name = typeof tool.name === "string" ? tool.name : "";
|
|
102
|
+
if (!name) return false;
|
|
103
|
+
const lc = lower(name);
|
|
104
|
+
if (CORE_TOOL_NAMES.has(lc)) return false;
|
|
105
|
+
if (lc.startsWith("mcp__")) return false;
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Transform tools[]; returns the surviving tools plus the flat→alias map of
|
|
110
|
+
// exactly what was renamed (so tool_choice / message history stay consistent).
|
|
111
|
+
function transformTools(tools: unknown[]): {
|
|
112
|
+
tools: unknown[];
|
|
113
|
+
renamed: Map<string, string>;
|
|
114
|
+
} {
|
|
115
|
+
const renamed = new Map<string, string>(); // lower(flat) → alias
|
|
116
|
+
const emitted = new Set<string>();
|
|
117
|
+
const result: unknown[] = [];
|
|
118
|
+
|
|
119
|
+
for (const tool of tools) {
|
|
120
|
+
if (!isPlainObject(tool)) continue;
|
|
121
|
+
|
|
122
|
+
if (!shouldRename(tool)) {
|
|
123
|
+
const key =
|
|
124
|
+
typeof tool.name === "string"
|
|
125
|
+
? lower(tool.name)
|
|
126
|
+
: `__native_${result.length}`;
|
|
127
|
+
if (emitted.has(key)) continue;
|
|
128
|
+
emitted.add(key);
|
|
129
|
+
result.push(tool);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const name = tool.name as string;
|
|
134
|
+
const alias = ALIAS_PREFIX + name;
|
|
135
|
+
renamed.set(lower(name), alias);
|
|
136
|
+
if (emitted.has(lower(alias))) continue;
|
|
137
|
+
emitted.add(lower(alias));
|
|
138
|
+
result.push({ ...tool, name: alias }); // preserves schema + cache_control
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return { tools: result, renamed };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Rewrite tool_use block names in message history to match the renamed tools.
|
|
145
|
+
function remapMessages(
|
|
146
|
+
messages: unknown[],
|
|
147
|
+
renamed: Map<string, string>,
|
|
148
|
+
): unknown[] {
|
|
149
|
+
if (renamed.size === 0) return messages;
|
|
150
|
+
let changed = false;
|
|
151
|
+
const next = messages.map((msg) => {
|
|
152
|
+
if (!isPlainObject(msg) || !Array.isArray(msg.content)) return msg;
|
|
153
|
+
let blockChanged = false;
|
|
154
|
+
const content = msg.content.map((block) => {
|
|
155
|
+
if (
|
|
156
|
+
!isPlainObject(block) ||
|
|
157
|
+
block.type !== "tool_use" ||
|
|
158
|
+
typeof block.name !== "string"
|
|
159
|
+
)
|
|
160
|
+
return block;
|
|
161
|
+
const alias = renamed.get(lower(block.name));
|
|
162
|
+
if (!alias || alias === block.name) return block;
|
|
163
|
+
blockChanged = true;
|
|
164
|
+
return { ...block, name: alias };
|
|
165
|
+
});
|
|
166
|
+
if (!blockChanged) return msg;
|
|
167
|
+
changed = true;
|
|
168
|
+
return { ...msg, content };
|
|
169
|
+
});
|
|
170
|
+
return changed ? next : messages;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function remapToolChoice(
|
|
174
|
+
toolChoice: Record<string, unknown>,
|
|
175
|
+
renamed: Map<string, string>,
|
|
176
|
+
): Record<string, unknown> {
|
|
177
|
+
if (toolChoice.type !== "tool" || typeof toolChoice.name !== "string")
|
|
178
|
+
return toolChoice;
|
|
179
|
+
const alias = renamed.get(lower(toolChoice.name));
|
|
180
|
+
return alias ? { ...toolChoice, name: alias } : toolChoice;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function transformPayload(
|
|
184
|
+
raw: Record<string, unknown>,
|
|
185
|
+
disable: boolean,
|
|
186
|
+
): Record<string, unknown> {
|
|
187
|
+
const payload = JSON.parse(JSON.stringify(raw)) as Record<string, unknown>;
|
|
188
|
+
|
|
189
|
+
// 1. System prompt rewrite always applies.
|
|
190
|
+
if (payload.system !== undefined)
|
|
191
|
+
payload.system = rewriteSystemField(payload.system);
|
|
192
|
+
|
|
193
|
+
if (disable) return payload;
|
|
194
|
+
|
|
195
|
+
// 2. Rename unknown flat tools → mcp__pi__<name>.
|
|
196
|
+
if (Array.isArray(payload.tools)) {
|
|
197
|
+
const { tools, renamed } = transformTools(payload.tools as unknown[]);
|
|
198
|
+
payload.tools = tools;
|
|
199
|
+
|
|
200
|
+
// 3. Keep tool_choice consistent.
|
|
201
|
+
if (isPlainObject(payload.tool_choice)) {
|
|
202
|
+
payload.tool_choice = remapToolChoice(payload.tool_choice, renamed);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 4. Keep historical tool_use names consistent with the renamed tools.
|
|
206
|
+
if (Array.isArray(payload.messages)) {
|
|
207
|
+
payload.messages = remapMessages(payload.messages, renamed);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return payload;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ─── Reverse mapping on execution ────────────────────────────────────────────
|
|
215
|
+
// Rewrite mcp__pi__<name> tool calls back to <name> in the finalized assistant
|
|
216
|
+
// message, BEFORE Pi resolves which tool to run. Only touches our own prefix,
|
|
217
|
+
// so foreign mcp__ tools (other extensions) are untouched.
|
|
218
|
+
function unaliasToolCalls(message: unknown): unknown {
|
|
219
|
+
if (
|
|
220
|
+
!isPlainObject(message) ||
|
|
221
|
+
message.role !== "assistant" ||
|
|
222
|
+
!Array.isArray(message.content)
|
|
223
|
+
)
|
|
224
|
+
return undefined;
|
|
225
|
+
let changed = false;
|
|
226
|
+
const content = message.content.map((block) => {
|
|
227
|
+
if (
|
|
228
|
+
!isPlainObject(block) ||
|
|
229
|
+
block.type !== "toolCall" ||
|
|
230
|
+
typeof block.name !== "string"
|
|
231
|
+
)
|
|
232
|
+
return block;
|
|
233
|
+
if (!block.name.startsWith(ALIAS_PREFIX)) return block;
|
|
234
|
+
changed = true;
|
|
235
|
+
return { ...block, name: block.name.slice(ALIAS_PREFIX.length) };
|
|
236
|
+
});
|
|
237
|
+
return changed ? { ...message, content } : undefined;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ─── Debug logging (optional) ─────────────────────────────────────────────────
|
|
241
|
+
const debugLogPath = process.env.PI_CLAUDE_PROVIDER_DEBUG_LOG;
|
|
242
|
+
function writeDebugLog(payload: unknown): void {
|
|
243
|
+
if (!debugLogPath) return;
|
|
244
|
+
try {
|
|
245
|
+
appendFileSync(
|
|
246
|
+
debugLogPath,
|
|
247
|
+
`${new Date().toISOString()}\n${JSON.stringify(payload, null, 2)}\n---\n`,
|
|
248
|
+
"utf-8",
|
|
249
|
+
);
|
|
250
|
+
} catch {
|
|
251
|
+
/* logging must never break a request */
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export default function piProviderClaude(pi: ExtensionAPI): void {
|
|
256
|
+
// mcp__pi__* → flat, before the agent loop resolves the tool.
|
|
257
|
+
pi.on("message_end", async (event, _ctx) => {
|
|
258
|
+
const rewritten = unaliasToolCalls(event.message);
|
|
259
|
+
if (!rewritten) return undefined;
|
|
260
|
+
return { message: rewritten as typeof event.message };
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
pi.on("before_provider_request", (event, ctx) => {
|
|
264
|
+
const model = ctx.model;
|
|
265
|
+
if (
|
|
266
|
+
!model ||
|
|
267
|
+
model.provider !== "anthropic" ||
|
|
268
|
+
!ctx.modelRegistry.isUsingOAuth(model)
|
|
269
|
+
) {
|
|
270
|
+
return undefined; // only Anthropic OAuth
|
|
271
|
+
}
|
|
272
|
+
if (!isPlainObject(event.payload)) return undefined;
|
|
273
|
+
|
|
274
|
+
writeDebugLog({ stage: "before", payload: event.payload });
|
|
275
|
+
const disable = process.env.PI_CLAUDE_PROVIDER_DISABLE === "1";
|
|
276
|
+
const transformed = transformPayload(
|
|
277
|
+
event.payload as Record<string, unknown>,
|
|
278
|
+
disable,
|
|
279
|
+
);
|
|
280
|
+
writeDebugLog({ stage: "after", payload: transformed });
|
|
281
|
+
return transformed;
|
|
282
|
+
});
|
|
283
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zgltyq/pi-provider-claude",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Claude (Anthropic OAuth/subscription) compatibility layer for pi-coding-agent — keeps ALL extension tools usable under the Claude subscription by mapping unknown flat tool names to mcp__pi__<name> on the wire instead of dropping them. Self-contained fork of the tool half of @benvargas/pi-claude-code-use.",
|
|
5
|
+
"author": "Leechael",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/ZGltYQ/pi-provider-claude"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/ZGltYQ/pi-provider-claude#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/ZGltYQ/pi-provider-claude/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"pi-package",
|
|
17
|
+
"pi-extension",
|
|
18
|
+
"pi-provider",
|
|
19
|
+
"pi",
|
|
20
|
+
"pi-coding-agent",
|
|
21
|
+
"pi-mono",
|
|
22
|
+
"coding-agent",
|
|
23
|
+
"anthropic",
|
|
24
|
+
"claude",
|
|
25
|
+
"claude-code",
|
|
26
|
+
"oauth",
|
|
27
|
+
"subscription",
|
|
28
|
+
"tools",
|
|
29
|
+
"fork"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"files": [
|
|
33
|
+
"index.ts",
|
|
34
|
+
"package.json",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"pi": {
|
|
39
|
+
"extensions": [
|
|
40
|
+
"./index.ts"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@earendil-works/pi-coding-agent": ">=0.74.0"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
49
|
+
}
|