@oh-my-pi/pi-coding-agent 1.337.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/CHANGELOG.md +1228 -0
- package/README.md +1041 -0
- package/docs/compaction.md +403 -0
- package/docs/custom-tools.md +541 -0
- package/docs/extension-loading.md +1004 -0
- package/docs/hooks.md +867 -0
- package/docs/rpc.md +1040 -0
- package/docs/sdk.md +994 -0
- package/docs/session-tree-plan.md +441 -0
- package/docs/session.md +240 -0
- package/docs/skills.md +290 -0
- package/docs/theme.md +637 -0
- package/docs/tree.md +197 -0
- package/docs/tui.md +341 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +124 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/custom-tools/question/index.ts +84 -0
- package/examples/custom-tools/subagent/README.md +172 -0
- package/examples/custom-tools/subagent/agents/planner.md +37 -0
- package/examples/custom-tools/subagent/agents/reviewer.md +35 -0
- package/examples/custom-tools/subagent/agents/scout.md +50 -0
- package/examples/custom-tools/subagent/agents/worker.md +24 -0
- package/examples/custom-tools/subagent/agents.ts +156 -0
- package/examples/custom-tools/subagent/commands/implement-and-review.md +10 -0
- package/examples/custom-tools/subagent/commands/implement.md +10 -0
- package/examples/custom-tools/subagent/commands/scout-and-plan.md +9 -0
- package/examples/custom-tools/subagent/index.ts +1002 -0
- package/examples/custom-tools/todo/index.ts +212 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +49 -0
- package/examples/hooks/confirm-destructive.ts +59 -0
- package/examples/hooks/custom-compaction.ts +116 -0
- package/examples/hooks/dirty-repo-guard.ts +52 -0
- package/examples/hooks/file-trigger.ts +41 -0
- package/examples/hooks/git-checkpoint.ts +53 -0
- package/examples/hooks/handoff.ts +150 -0
- package/examples/hooks/permission-gate.ts +34 -0
- package/examples/hooks/protected-paths.ts +30 -0
- package/examples/hooks/qna.ts +119 -0
- package/examples/hooks/snake.ts +343 -0
- package/examples/hooks/status-line.ts +40 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +44 -0
- package/examples/sdk/04-skills.ts +44 -0
- package/examples/sdk/05-tools.ts +90 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +36 -0
- package/examples/sdk/08-slash-commands.ts +42 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +55 -0
- package/examples/sdk/10-settings.ts +38 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +95 -0
- package/examples/sdk/README.md +154 -0
- package/package.json +81 -0
- package/src/cli/args.ts +246 -0
- package/src/cli/file-processor.ts +72 -0
- package/src/cli/list-models.ts +104 -0
- package/src/cli/plugin-cli.ts +650 -0
- package/src/cli/session-picker.ts +41 -0
- package/src/cli.ts +10 -0
- package/src/commands/init.md +20 -0
- package/src/config.ts +159 -0
- package/src/core/agent-session.ts +1900 -0
- package/src/core/auth-storage.ts +236 -0
- package/src/core/bash-executor.ts +196 -0
- package/src/core/compaction/branch-summarization.ts +343 -0
- package/src/core/compaction/compaction.ts +742 -0
- package/src/core/compaction/index.ts +7 -0
- package/src/core/compaction/utils.ts +154 -0
- package/src/core/custom-tools/index.ts +21 -0
- package/src/core/custom-tools/loader.ts +248 -0
- package/src/core/custom-tools/types.ts +169 -0
- package/src/core/custom-tools/wrapper.ts +28 -0
- package/src/core/exec.ts +129 -0
- package/src/core/export-html/index.ts +211 -0
- package/src/core/export-html/template.css +781 -0
- package/src/core/export-html/template.html +54 -0
- package/src/core/export-html/template.js +1185 -0
- package/src/core/export-html/vendor/highlight.min.js +1213 -0
- package/src/core/export-html/vendor/marked.min.js +6 -0
- package/src/core/hooks/index.ts +16 -0
- package/src/core/hooks/loader.ts +312 -0
- package/src/core/hooks/runner.ts +434 -0
- package/src/core/hooks/tool-wrapper.ts +99 -0
- package/src/core/hooks/types.ts +773 -0
- package/src/core/index.ts +52 -0
- package/src/core/mcp/client.ts +158 -0
- package/src/core/mcp/config.ts +154 -0
- package/src/core/mcp/index.ts +45 -0
- package/src/core/mcp/loader.ts +68 -0
- package/src/core/mcp/manager.ts +181 -0
- package/src/core/mcp/tool-bridge.ts +148 -0
- package/src/core/mcp/transports/http.ts +316 -0
- package/src/core/mcp/transports/index.ts +6 -0
- package/src/core/mcp/transports/stdio.ts +252 -0
- package/src/core/mcp/types.ts +220 -0
- package/src/core/messages.ts +189 -0
- package/src/core/model-registry.ts +317 -0
- package/src/core/model-resolver.ts +393 -0
- package/src/core/plugins/doctor.ts +59 -0
- package/src/core/plugins/index.ts +38 -0
- package/src/core/plugins/installer.ts +189 -0
- package/src/core/plugins/loader.ts +338 -0
- package/src/core/plugins/manager.ts +672 -0
- package/src/core/plugins/parser.ts +105 -0
- package/src/core/plugins/paths.ts +32 -0
- package/src/core/plugins/types.ts +190 -0
- package/src/core/sdk.ts +760 -0
- package/src/core/session-manager.ts +1128 -0
- package/src/core/settings-manager.ts +443 -0
- package/src/core/skills.ts +437 -0
- package/src/core/slash-commands.ts +248 -0
- package/src/core/system-prompt.ts +439 -0
- package/src/core/timings.ts +25 -0
- package/src/core/tools/ask.ts +211 -0
- package/src/core/tools/bash-interceptor.ts +120 -0
- package/src/core/tools/bash.ts +250 -0
- package/src/core/tools/context.ts +32 -0
- package/src/core/tools/edit-diff.ts +475 -0
- package/src/core/tools/edit.ts +208 -0
- package/src/core/tools/exa/company.ts +59 -0
- package/src/core/tools/exa/index.ts +64 -0
- package/src/core/tools/exa/linkedin.ts +59 -0
- package/src/core/tools/exa/logger.ts +56 -0
- package/src/core/tools/exa/mcp-client.ts +368 -0
- package/src/core/tools/exa/render.ts +196 -0
- package/src/core/tools/exa/researcher.ts +90 -0
- package/src/core/tools/exa/search.ts +337 -0
- package/src/core/tools/exa/types.ts +168 -0
- package/src/core/tools/exa/websets.ts +248 -0
- package/src/core/tools/find.ts +261 -0
- package/src/core/tools/grep.ts +555 -0
- package/src/core/tools/index.ts +202 -0
- package/src/core/tools/ls.ts +140 -0
- package/src/core/tools/lsp/client.ts +605 -0
- package/src/core/tools/lsp/config.ts +147 -0
- package/src/core/tools/lsp/edits.ts +101 -0
- package/src/core/tools/lsp/index.ts +804 -0
- package/src/core/tools/lsp/render.ts +447 -0
- package/src/core/tools/lsp/rust-analyzer.ts +145 -0
- package/src/core/tools/lsp/types.ts +463 -0
- package/src/core/tools/lsp/utils.ts +486 -0
- package/src/core/tools/notebook.ts +229 -0
- package/src/core/tools/path-utils.ts +61 -0
- package/src/core/tools/read.ts +240 -0
- package/src/core/tools/renderers.ts +540 -0
- package/src/core/tools/task/agents.ts +153 -0
- package/src/core/tools/task/artifacts.ts +114 -0
- package/src/core/tools/task/bundled-agents/browser.md +71 -0
- package/src/core/tools/task/bundled-agents/explore.md +82 -0
- package/src/core/tools/task/bundled-agents/plan.md +54 -0
- package/src/core/tools/task/bundled-agents/reviewer.md +59 -0
- package/src/core/tools/task/bundled-agents/task.md +53 -0
- package/src/core/tools/task/bundled-commands/architect-plan.md +10 -0
- package/src/core/tools/task/bundled-commands/implement-with-critic.md +11 -0
- package/src/core/tools/task/bundled-commands/implement.md +11 -0
- package/src/core/tools/task/commands.ts +213 -0
- package/src/core/tools/task/discovery.ts +208 -0
- package/src/core/tools/task/executor.ts +367 -0
- package/src/core/tools/task/index.ts +388 -0
- package/src/core/tools/task/model-resolver.ts +115 -0
- package/src/core/tools/task/parallel.ts +38 -0
- package/src/core/tools/task/render.ts +232 -0
- package/src/core/tools/task/types.ts +99 -0
- package/src/core/tools/truncate.ts +265 -0
- package/src/core/tools/web-fetch.ts +2370 -0
- package/src/core/tools/web-search/auth.ts +193 -0
- package/src/core/tools/web-search/index.ts +537 -0
- package/src/core/tools/web-search/providers/anthropic.ts +198 -0
- package/src/core/tools/web-search/providers/exa.ts +302 -0
- package/src/core/tools/web-search/providers/perplexity.ts +195 -0
- package/src/core/tools/web-search/render.ts +182 -0
- package/src/core/tools/web-search/types.ts +180 -0
- package/src/core/tools/write.ts +99 -0
- package/src/index.ts +176 -0
- package/src/main.ts +464 -0
- package/src/migrations.ts +135 -0
- package/src/modes/index.ts +43 -0
- package/src/modes/interactive/components/armin.ts +382 -0
- package/src/modes/interactive/components/assistant-message.ts +86 -0
- package/src/modes/interactive/components/bash-execution.ts +196 -0
- package/src/modes/interactive/components/bordered-loader.ts +41 -0
- package/src/modes/interactive/components/branch-summary-message.ts +42 -0
- package/src/modes/interactive/components/compaction-summary-message.ts +45 -0
- package/src/modes/interactive/components/custom-editor.ts +122 -0
- package/src/modes/interactive/components/diff.ts +147 -0
- package/src/modes/interactive/components/dynamic-border.ts +25 -0
- package/src/modes/interactive/components/footer.ts +381 -0
- package/src/modes/interactive/components/hook-editor.ts +117 -0
- package/src/modes/interactive/components/hook-input.ts +64 -0
- package/src/modes/interactive/components/hook-message.ts +96 -0
- package/src/modes/interactive/components/hook-selector.ts +91 -0
- package/src/modes/interactive/components/model-selector.ts +247 -0
- package/src/modes/interactive/components/oauth-selector.ts +120 -0
- package/src/modes/interactive/components/plugin-settings.ts +479 -0
- package/src/modes/interactive/components/queue-mode-selector.ts +56 -0
- package/src/modes/interactive/components/session-selector.ts +204 -0
- package/src/modes/interactive/components/settings-selector.ts +453 -0
- package/src/modes/interactive/components/show-images-selector.ts +45 -0
- package/src/modes/interactive/components/theme-selector.ts +62 -0
- package/src/modes/interactive/components/thinking-selector.ts +64 -0
- package/src/modes/interactive/components/tool-execution.ts +675 -0
- package/src/modes/interactive/components/tree-selector.ts +866 -0
- package/src/modes/interactive/components/user-message-selector.ts +159 -0
- package/src/modes/interactive/components/user-message.ts +18 -0
- package/src/modes/interactive/components/visual-truncate.ts +50 -0
- package/src/modes/interactive/components/welcome.ts +183 -0
- package/src/modes/interactive/interactive-mode.ts +2516 -0
- package/src/modes/interactive/theme/dark.json +101 -0
- package/src/modes/interactive/theme/light.json +98 -0
- package/src/modes/interactive/theme/theme-schema.json +308 -0
- package/src/modes/interactive/theme/theme.ts +998 -0
- package/src/modes/print-mode.ts +128 -0
- package/src/modes/rpc/rpc-client.ts +527 -0
- package/src/modes/rpc/rpc-mode.ts +483 -0
- package/src/modes/rpc/rpc-types.ts +203 -0
- package/src/utils/changelog.ts +99 -0
- package/src/utils/clipboard.ts +265 -0
- package/src/utils/fuzzy.ts +108 -0
- package/src/utils/mime.ts +30 -0
- package/src/utils/shell.ts +276 -0
- package/src/utils/tools-manager.ts +274 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Authentication
|
|
3
|
+
*
|
|
4
|
+
* 4-tier auth resolution:
|
|
5
|
+
* 1. ANTHROPIC_SEARCH_API_KEY / ANTHROPIC_SEARCH_BASE_URL env vars
|
|
6
|
+
* 2. Provider with api="anthropic-messages" in ~/.pi/agent/models.json
|
|
7
|
+
* 3. OAuth credentials in ~/.pi/agent/auth.json (with expiry check)
|
|
8
|
+
* 4. ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL fallback
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as os from "node:os";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import type { AnthropicAuthConfig, AuthJson, ModelsJson } from "./types.js";
|
|
14
|
+
|
|
15
|
+
const DEFAULT_BASE_URL = "https://api.anthropic.com";
|
|
16
|
+
|
|
17
|
+
/** Parse a .env file and return key-value pairs */
|
|
18
|
+
async function parseEnvFile(filePath: string): Promise<Record<string, string>> {
|
|
19
|
+
const result: Record<string, string> = {};
|
|
20
|
+
try {
|
|
21
|
+
const file = Bun.file(filePath);
|
|
22
|
+
if (!(await file.exists())) return result;
|
|
23
|
+
|
|
24
|
+
const content = await file.text();
|
|
25
|
+
for (const line of content.split("\n")) {
|
|
26
|
+
const trimmed = line.trim();
|
|
27
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
28
|
+
|
|
29
|
+
const eqIndex = trimmed.indexOf("=");
|
|
30
|
+
if (eqIndex === -1) continue;
|
|
31
|
+
|
|
32
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
33
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
34
|
+
|
|
35
|
+
// Remove surrounding quotes
|
|
36
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
|
|
37
|
+
value = value.slice(1, -1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
result[key] = value;
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
// Ignore read errors
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Get env var from process.env or .env files */
|
|
49
|
+
export async function getEnv(key: string): Promise<string | undefined> {
|
|
50
|
+
if (process.env[key]) return process.env[key];
|
|
51
|
+
|
|
52
|
+
const localEnv = await parseEnvFile(`${process.cwd()}/.env`);
|
|
53
|
+
if (localEnv[key]) return localEnv[key];
|
|
54
|
+
|
|
55
|
+
const homeEnv = await parseEnvFile(`${os.homedir()}/.env`);
|
|
56
|
+
if (homeEnv[key]) return homeEnv[key];
|
|
57
|
+
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Read JSON file safely */
|
|
62
|
+
async function readJson<T>(filePath: string): Promise<T | null> {
|
|
63
|
+
try {
|
|
64
|
+
const file = Bun.file(filePath);
|
|
65
|
+
if (!(await file.exists())) return null;
|
|
66
|
+
const content = await file.text();
|
|
67
|
+
return JSON.parse(content) as T;
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Check if a token is an OAuth token (sk-ant-oat* prefix) */
|
|
74
|
+
export function isOAuthToken(apiKey: string): boolean {
|
|
75
|
+
return apiKey.includes("sk-ant-oat");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Find Anthropic auth config using 4-tier priority:
|
|
80
|
+
* 1. ANTHROPIC_SEARCH_API_KEY / ANTHROPIC_SEARCH_BASE_URL
|
|
81
|
+
* 2. Provider with api="anthropic-messages" in models.json
|
|
82
|
+
* 3. OAuth in auth.json (with 5-minute expiry buffer)
|
|
83
|
+
* 4. ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL fallback
|
|
84
|
+
*/
|
|
85
|
+
export async function findAnthropicAuth(): Promise<AnthropicAuthConfig | null> {
|
|
86
|
+
const piAgentDir = path.join(os.homedir(), ".pi", "agent");
|
|
87
|
+
|
|
88
|
+
// 1. Explicit search-specific env vars
|
|
89
|
+
const searchApiKey = await getEnv("ANTHROPIC_SEARCH_API_KEY");
|
|
90
|
+
const searchBaseUrl = await getEnv("ANTHROPIC_SEARCH_BASE_URL");
|
|
91
|
+
if (searchApiKey) {
|
|
92
|
+
return {
|
|
93
|
+
apiKey: searchApiKey,
|
|
94
|
+
baseUrl: searchBaseUrl ?? DEFAULT_BASE_URL,
|
|
95
|
+
isOAuth: isOAuthToken(searchApiKey),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 2. Provider with api="anthropic-messages" in models.json
|
|
100
|
+
const modelsJson = await readJson<ModelsJson>(path.join(piAgentDir, "models.json"));
|
|
101
|
+
if (modelsJson?.providers) {
|
|
102
|
+
// First pass: look for providers with actual API keys
|
|
103
|
+
for (const [_name, provider] of Object.entries(modelsJson.providers)) {
|
|
104
|
+
if (provider.api === "anthropic-messages" && provider.apiKey && provider.apiKey !== "none") {
|
|
105
|
+
return {
|
|
106
|
+
apiKey: provider.apiKey,
|
|
107
|
+
baseUrl: provider.baseUrl ?? DEFAULT_BASE_URL,
|
|
108
|
+
isOAuth: isOAuthToken(provider.apiKey),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Second pass: check for proxy mode (baseUrl but apiKey="none")
|
|
113
|
+
for (const [_name, provider] of Object.entries(modelsJson.providers)) {
|
|
114
|
+
if (provider.api === "anthropic-messages" && provider.baseUrl) {
|
|
115
|
+
return {
|
|
116
|
+
apiKey: provider.apiKey ?? "",
|
|
117
|
+
baseUrl: provider.baseUrl,
|
|
118
|
+
isOAuth: false,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 3. OAuth credentials in auth.json (with 5-minute expiry buffer)
|
|
125
|
+
const authJson = await readJson<AuthJson>(path.join(piAgentDir, "auth.json"));
|
|
126
|
+
if (authJson?.anthropic?.type === "oauth" && authJson.anthropic.access) {
|
|
127
|
+
const expiryBuffer = 5 * 60 * 1000; // 5 minutes
|
|
128
|
+
if (authJson.anthropic.expires > Date.now() + expiryBuffer) {
|
|
129
|
+
return {
|
|
130
|
+
apiKey: authJson.anthropic.access,
|
|
131
|
+
baseUrl: DEFAULT_BASE_URL,
|
|
132
|
+
isOAuth: true,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 4. Generic ANTHROPIC_API_KEY fallback
|
|
138
|
+
const apiKey = await getEnv("ANTHROPIC_API_KEY");
|
|
139
|
+
const baseUrl = await getEnv("ANTHROPIC_BASE_URL");
|
|
140
|
+
if (apiKey) {
|
|
141
|
+
return {
|
|
142
|
+
apiKey,
|
|
143
|
+
baseUrl: baseUrl ?? DEFAULT_BASE_URL,
|
|
144
|
+
isOAuth: isOAuthToken(apiKey),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Build headers for Anthropic API request */
|
|
152
|
+
export function buildAnthropicHeaders(auth: AnthropicAuthConfig): Record<string, string> {
|
|
153
|
+
const betas = ["web-search-2025-03-05"];
|
|
154
|
+
|
|
155
|
+
if (auth.isOAuth) {
|
|
156
|
+
// OAuth requires additional beta headers and stainless telemetry
|
|
157
|
+
betas.push("oauth-2025-04-20", "claude-code-20250219", "prompt-caching-2024-07-31");
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
"anthropic-version": "2023-06-01",
|
|
161
|
+
authorization: `Bearer ${auth.apiKey}`,
|
|
162
|
+
accept: "application/json",
|
|
163
|
+
"content-type": "application/json",
|
|
164
|
+
"anthropic-dangerous-direct-browser-access": "true",
|
|
165
|
+
"anthropic-beta": betas.join(","),
|
|
166
|
+
"user-agent": "pi-coding-agent/1.0.0 (cli)",
|
|
167
|
+
"x-app": "cli",
|
|
168
|
+
// Stainless SDK telemetry headers (required for OAuth)
|
|
169
|
+
"x-stainless-arch": process.arch,
|
|
170
|
+
"x-stainless-lang": "js",
|
|
171
|
+
"x-stainless-os": process.platform,
|
|
172
|
+
"x-stainless-package-version": "1.0.0",
|
|
173
|
+
"x-stainless-retry-count": "0",
|
|
174
|
+
"x-stainless-runtime": "bun",
|
|
175
|
+
"x-stainless-runtime-version": Bun.version,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Standard API key auth
|
|
180
|
+
return {
|
|
181
|
+
"anthropic-version": "2023-06-01",
|
|
182
|
+
"x-api-key": auth.apiKey,
|
|
183
|
+
accept: "application/json",
|
|
184
|
+
"content-type": "application/json",
|
|
185
|
+
"anthropic-beta": betas.join(","),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Build API URL (OAuth requires ?beta=true) */
|
|
190
|
+
export function buildAnthropicUrl(auth: AnthropicAuthConfig): string {
|
|
191
|
+
const base = `${auth.baseUrl}/v1/messages`;
|
|
192
|
+
return auth.isOAuth ? `${base}?beta=true` : base;
|
|
193
|
+
}
|