@oh-my-pi/pi-coding-agent 1.340.0 → 2.0.1337
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 +115 -1
- package/README.md +1 -1
- package/examples/custom-tools/subagent/index.ts +1 -1
- package/package.json +5 -3
- package/src/cli/args.ts +13 -6
- package/src/cli/file-processor.ts +3 -3
- package/src/cli/list-models.ts +2 -2
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/session-picker.ts +2 -2
- package/src/cli.ts +1 -1
- package/src/config.ts +3 -3
- package/src/core/agent-session.ts +189 -29
- package/src/core/bash-executor.ts +50 -10
- package/src/core/compaction/branch-summarization.ts +5 -5
- package/src/core/compaction/compaction.ts +3 -3
- package/src/core/compaction/index.ts +3 -3
- package/src/core/custom-commands/bundled/review/index.ts +156 -0
- package/src/core/custom-commands/index.ts +15 -0
- package/src/core/custom-commands/loader.ts +232 -0
- package/src/core/custom-commands/types.ts +112 -0
- package/src/core/custom-tools/index.ts +3 -3
- package/src/core/custom-tools/loader.ts +10 -8
- package/src/core/custom-tools/types.ts +11 -6
- package/src/core/custom-tools/wrapper.ts +2 -1
- package/src/core/exec.ts +22 -12
- package/src/core/export-html/index.ts +5 -5
- package/src/core/file-mentions.ts +54 -0
- package/src/core/hooks/index.ts +5 -5
- package/src/core/hooks/loader.ts +21 -16
- package/src/core/hooks/runner.ts +6 -6
- package/src/core/hooks/tool-wrapper.ts +2 -2
- package/src/core/hooks/types.ts +12 -15
- package/src/core/index.ts +6 -6
- package/src/core/logger.ts +112 -0
- package/src/core/mcp/client.ts +3 -3
- package/src/core/mcp/config.ts +1 -1
- package/src/core/mcp/index.ts +12 -12
- package/src/core/mcp/loader.ts +2 -2
- package/src/core/mcp/manager.ts +6 -6
- package/src/core/mcp/tool-bridge.ts +3 -3
- package/src/core/mcp/transports/http.ts +1 -1
- package/src/core/mcp/transports/index.ts +2 -2
- package/src/core/mcp/transports/stdio.ts +1 -1
- package/src/core/messages.ts +22 -0
- package/src/core/model-registry.ts +2 -2
- package/src/core/model-resolver.ts +103 -2
- package/src/core/plugins/doctor.ts +1 -1
- package/src/core/plugins/index.ts +6 -6
- package/src/core/plugins/installer.ts +4 -4
- package/src/core/plugins/loader.ts +4 -9
- package/src/core/plugins/manager.ts +5 -5
- package/src/core/plugins/paths.ts +3 -3
- package/src/core/sdk.ts +127 -52
- package/src/core/session-manager.ts +123 -20
- package/src/core/settings-manager.ts +106 -22
- package/src/core/skills.ts +5 -5
- package/src/core/slash-commands.ts +60 -45
- package/src/core/system-prompt.ts +6 -6
- package/src/core/title-generator.ts +94 -0
- package/src/core/tools/bash.ts +33 -157
- package/src/core/tools/context.ts +2 -2
- package/src/core/tools/edit-diff.ts +5 -5
- package/src/core/tools/edit.ts +60 -9
- package/src/core/tools/exa/company.ts +3 -3
- package/src/core/tools/exa/index.ts +16 -17
- package/src/core/tools/exa/linkedin.ts +3 -3
- package/src/core/tools/exa/mcp-client.ts +9 -9
- package/src/core/tools/exa/render.ts +5 -5
- package/src/core/tools/exa/researcher.ts +3 -3
- package/src/core/tools/exa/search.ts +6 -5
- package/src/core/tools/exa/types.ts +5 -6
- package/src/core/tools/exa/websets.ts +3 -3
- package/src/core/tools/find.ts +3 -3
- package/src/core/tools/grep.ts +6 -5
- package/src/core/tools/index.ts +114 -40
- package/src/core/tools/ls.ts +4 -4
- package/src/core/tools/lsp/client.ts +204 -108
- package/src/core/tools/lsp/config.ts +709 -35
- package/src/core/tools/lsp/edits.ts +2 -2
- package/src/core/tools/lsp/index.ts +432 -30
- package/src/core/tools/lsp/render.ts +2 -2
- package/src/core/tools/lsp/rust-analyzer.ts +3 -3
- package/src/core/tools/lsp/types.ts +5 -0
- package/src/core/tools/lsp/utils.ts +1 -1
- package/src/core/tools/notebook.ts +1 -1
- package/src/core/tools/output.ts +175 -0
- package/src/core/tools/read.ts +7 -7
- package/src/core/tools/renderers.ts +92 -13
- package/src/core/tools/review.ts +268 -0
- package/src/core/tools/task/agents.ts +1 -1
- package/src/core/tools/task/bundled-agents/explore.md +1 -1
- package/src/core/tools/task/bundled-agents/reviewer.md +53 -38
- package/src/core/tools/task/discovery.ts +2 -2
- package/src/core/tools/task/executor.ts +145 -28
- package/src/core/tools/task/index.ts +78 -30
- package/src/core/tools/task/model-resolver.ts +72 -13
- package/src/core/tools/task/parallel.ts +1 -1
- package/src/core/tools/task/render.ts +219 -30
- package/src/core/tools/task/subprocess-tool-registry.ts +89 -0
- package/src/core/tools/task/types.ts +36 -2
- package/src/core/tools/web-fetch.ts +5 -3
- package/src/core/tools/web-search/auth.ts +1 -1
- package/src/core/tools/web-search/index.ts +17 -15
- package/src/core/tools/web-search/providers/anthropic.ts +2 -2
- package/src/core/tools/web-search/providers/exa.ts +3 -5
- package/src/core/tools/web-search/providers/perplexity.ts +1 -1
- package/src/core/tools/web-search/render.ts +3 -3
- package/src/core/tools/write.ts +70 -7
- package/src/index.ts +33 -17
- package/src/main.ts +60 -34
- package/src/migrations.ts +3 -3
- package/src/modes/index.ts +5 -5
- package/src/modes/interactive/components/armin.ts +1 -1
- package/src/modes/interactive/components/assistant-message.ts +1 -1
- package/src/modes/interactive/components/bash-execution.ts +4 -4
- package/src/modes/interactive/components/bordered-loader.ts +2 -2
- package/src/modes/interactive/components/branch-summary-message.ts +2 -2
- package/src/modes/interactive/components/compaction-summary-message.ts +2 -2
- package/src/modes/interactive/components/diff.ts +1 -1
- package/src/modes/interactive/components/dynamic-border.ts +1 -1
- package/src/modes/interactive/components/footer.ts +5 -5
- package/src/modes/interactive/components/hook-editor.ts +2 -2
- package/src/modes/interactive/components/hook-input.ts +2 -2
- package/src/modes/interactive/components/hook-message.ts +3 -3
- package/src/modes/interactive/components/hook-selector.ts +2 -2
- package/src/modes/interactive/components/model-selector.ts +341 -41
- package/src/modes/interactive/components/oauth-selector.ts +3 -3
- package/src/modes/interactive/components/plugin-settings.ts +4 -4
- package/src/modes/interactive/components/queue-mode-selector.ts +2 -2
- package/src/modes/interactive/components/session-selector.ts +24 -11
- package/src/modes/interactive/components/settings-defs.ts +51 -3
- package/src/modes/interactive/components/settings-selector.ts +13 -16
- package/src/modes/interactive/components/show-images-selector.ts +2 -2
- package/src/modes/interactive/components/theme-selector.ts +2 -2
- package/src/modes/interactive/components/thinking-selector.ts +2 -2
- package/src/modes/interactive/components/tool-execution.ts +44 -8
- package/src/modes/interactive/components/tree-selector.ts +5 -5
- package/src/modes/interactive/components/user-message-selector.ts +2 -2
- package/src/modes/interactive/components/user-message.ts +1 -1
- package/src/modes/interactive/components/welcome.ts +42 -5
- package/src/modes/interactive/interactive-mode.ts +169 -48
- package/src/modes/interactive/theme/theme.ts +8 -7
- package/src/modes/print-mode.ts +4 -3
- package/src/modes/rpc/rpc-client.ts +4 -4
- package/src/modes/rpc/rpc-mode.ts +21 -11
- package/src/modes/rpc/rpc-types.ts +3 -3
- package/src/utils/changelog.ts +2 -2
- package/src/utils/clipboard.ts +1 -1
- package/src/utils/shell-snapshot.ts +218 -0
- package/src/utils/shell.ts +93 -13
- package/src/utils/tools-manager.ts +1 -1
- package/examples/custom-tools/subagent/agents/reviewer.md +0 -35
- package/src/core/tools/exa/logger.ts +0 -56
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
16
16
|
import { Type } from "@sinclair/typebox";
|
|
17
|
-
import type { Theme } from "../../../modes/interactive/theme/theme
|
|
18
|
-
import type { CustomTool, CustomToolContext, RenderResultOptions } from "../../custom-tools/types
|
|
19
|
-
import { callExaTool, findApiKey as findExaKey, formatSearchResults, isSearchResponse } from "../exa/mcp-client
|
|
20
|
-
import { renderExaCall, renderExaResult } from "../exa/render
|
|
21
|
-
import type { ExaRenderDetails } from "../exa/types
|
|
22
|
-
import { searchAnthropic } from "./providers/anthropic
|
|
23
|
-
import { searchExa } from "./providers/exa
|
|
24
|
-
import { findApiKey as findPerplexityKey, searchPerplexity } from "./providers/perplexity
|
|
25
|
-
import { formatAge, renderWebSearchCall, renderWebSearchResult, type WebSearchRenderDetails } from "./render
|
|
26
|
-
import type { WebSearchProvider, WebSearchResponse } from "./types
|
|
17
|
+
import type { Theme } from "../../../modes/interactive/theme/theme";
|
|
18
|
+
import type { CustomTool, CustomToolContext, RenderResultOptions } from "../../custom-tools/types";
|
|
19
|
+
import { callExaTool, findApiKey as findExaKey, formatSearchResults, isSearchResponse } from "../exa/mcp-client";
|
|
20
|
+
import { renderExaCall, renderExaResult } from "../exa/render";
|
|
21
|
+
import type { ExaRenderDetails } from "../exa/types";
|
|
22
|
+
import { searchAnthropic } from "./providers/anthropic";
|
|
23
|
+
import { searchExa } from "./providers/exa";
|
|
24
|
+
import { findApiKey as findPerplexityKey, searchPerplexity } from "./providers/perplexity";
|
|
25
|
+
import { formatAge, renderWebSearchCall, renderWebSearchResult, type WebSearchRenderDetails } from "./render";
|
|
26
|
+
import type { WebSearchProvider, WebSearchResponse } from "./types";
|
|
27
27
|
|
|
28
28
|
/** Web search parameters schema */
|
|
29
29
|
export const webSearchSchema = Type.Object({
|
|
@@ -345,7 +345,9 @@ Parameters:
|
|
|
345
345
|
parameters: webSearchDeepSchema,
|
|
346
346
|
|
|
347
347
|
async execute(_toolCallId, params, _onUpdate, _ctx, _signal) {
|
|
348
|
-
|
|
348
|
+
const { num_results, ...rest } = params as Record<string, unknown>;
|
|
349
|
+
const args = { ...rest, type: "deep", numResults: num_results ?? 10 };
|
|
350
|
+
return executeExaTool("web_search_exa", args, "web_search_deep");
|
|
349
351
|
},
|
|
350
352
|
|
|
351
353
|
renderCall(args, theme) {
|
|
@@ -404,7 +406,7 @@ Parameters:
|
|
|
404
406
|
parameters: webSearchCrawlSchema,
|
|
405
407
|
|
|
406
408
|
async execute(_toolCallId, params, _onUpdate, _ctx, _signal) {
|
|
407
|
-
return executeExaTool("
|
|
409
|
+
return executeExaTool("crawling", params as Record<string, unknown>, "web_search_crawl");
|
|
408
410
|
},
|
|
409
411
|
|
|
410
412
|
renderCall(args, theme) {
|
|
@@ -435,7 +437,7 @@ Parameters:
|
|
|
435
437
|
parameters: webSearchLinkedinSchema,
|
|
436
438
|
|
|
437
439
|
async execute(_toolCallId, params, _onUpdate, _ctx, _signal) {
|
|
438
|
-
return executeExaTool("
|
|
440
|
+
return executeExaTool("linkedin_search", params as Record<string, unknown>, "web_search_linkedin");
|
|
439
441
|
},
|
|
440
442
|
|
|
441
443
|
renderCall(args, theme) {
|
|
@@ -465,7 +467,7 @@ Parameters:
|
|
|
465
467
|
parameters: webSearchCompanySchema,
|
|
466
468
|
|
|
467
469
|
async execute(_toolCallId, params, _onUpdate, _ctx, _signal) {
|
|
468
|
-
return executeExaTool("
|
|
470
|
+
return executeExaTool("company_research", params as Record<string, unknown>, "web_search_company");
|
|
469
471
|
},
|
|
470
472
|
|
|
471
473
|
renderCall(args, theme) {
|
|
@@ -534,4 +536,4 @@ export async function hasExaWebSearch(): Promise<boolean> {
|
|
|
534
536
|
return exaKey !== null;
|
|
535
537
|
}
|
|
536
538
|
|
|
537
|
-
export type { WebSearchProvider, WebSearchResponse } from "./types
|
|
539
|
+
export type { WebSearchProvider, WebSearchResponse } from "./types";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Returns synthesized answers with citations and source metadata.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { buildAnthropicHeaders, buildAnthropicUrl, findAnthropicAuth, getEnv } from "../auth
|
|
8
|
+
import { buildAnthropicHeaders, buildAnthropicUrl, findAnthropicAuth, getEnv } from "../auth";
|
|
9
9
|
import type {
|
|
10
10
|
AnthropicApiResponse,
|
|
11
11
|
AnthropicAuthConfig,
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
WebSearchCitation,
|
|
14
14
|
WebSearchResponse,
|
|
15
15
|
WebSearchSource,
|
|
16
|
-
} from "../types
|
|
16
|
+
} from "../types";
|
|
17
17
|
|
|
18
18
|
const DEFAULT_MODEL = "claude-sonnet-4-5-20250514";
|
|
19
19
|
const DEFAULT_MAX_TOKENS = 4096;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as os from "node:os";
|
|
9
|
-
import type { WebSearchResponse, WebSearchSource } from "../types
|
|
9
|
+
import type { WebSearchResponse, WebSearchSource } from "../types";
|
|
10
10
|
|
|
11
11
|
const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
|
|
12
12
|
|
|
@@ -248,10 +248,8 @@ export async function searchExa(params: ExaSearchParams): Promise<WebSearchRespo
|
|
|
248
248
|
|
|
249
249
|
const args: Record<string, unknown> = {
|
|
250
250
|
query: params.query,
|
|
251
|
-
|
|
251
|
+
numResults: params.num_results ?? 10,
|
|
252
252
|
type: params.type ?? "auto",
|
|
253
|
-
text: true, // Include text for richer results
|
|
254
|
-
highlights: true,
|
|
255
253
|
};
|
|
256
254
|
|
|
257
255
|
if (params.include_domains?.length) {
|
|
@@ -267,7 +265,7 @@ export async function searchExa(params: ExaSearchParams): Promise<WebSearchRespo
|
|
|
267
265
|
args.end_published_date = params.end_published_date;
|
|
268
266
|
}
|
|
269
267
|
|
|
270
|
-
const response = await callExaMCP(apiKey, "
|
|
268
|
+
const response = await callExaMCP(apiKey, "web_search_exa", args);
|
|
271
269
|
|
|
272
270
|
if (response.error) {
|
|
273
271
|
throw new Error(`Exa MCP error: ${response.error.message}`);
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
8
8
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
9
|
-
import type { Theme } from "../../../modes/interactive/theme/theme
|
|
10
|
-
import type { RenderResultOptions } from "../../custom-tools/types
|
|
11
|
-
import type { WebSearchResponse } from "./types
|
|
9
|
+
import type { Theme } from "../../../modes/interactive/theme/theme";
|
|
10
|
+
import type { RenderResultOptions } from "../../custom-tools/types";
|
|
11
|
+
import type { WebSearchResponse } from "./types";
|
|
12
12
|
|
|
13
13
|
// Tree formatting constants
|
|
14
14
|
const TREE_MID = "├─";
|
package/src/core/tools/write.ts
CHANGED
|
@@ -1,15 +1,39 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname } from "node:path";
|
|
1
3
|
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
2
4
|
import { Type } from "@sinclair/typebox";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { resolveToCwd } from "./path-utils.js";
|
|
5
|
+
import type { FileDiagnosticsResult, FileFormatResult } from "./lsp/index";
|
|
6
|
+
import { resolveToCwd } from "./path-utils";
|
|
6
7
|
|
|
7
8
|
const writeSchema = Type.Object({
|
|
8
9
|
path: Type.String({ description: "Path to the file to write (relative or absolute)" }),
|
|
9
10
|
content: Type.String({ description: "Content to write to the file" }),
|
|
10
11
|
});
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
/** Options for creating the write tool */
|
|
14
|
+
export interface WriteToolOptions {
|
|
15
|
+
/** Callback to format file using LSP after writing */
|
|
16
|
+
formatOnWrite?: (absolutePath: string) => Promise<FileFormatResult>;
|
|
17
|
+
/** Callback to get LSP diagnostics after writing a file */
|
|
18
|
+
getDiagnostics?: (absolutePath: string) => Promise<FileDiagnosticsResult>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Details returned by the write tool for TUI rendering */
|
|
22
|
+
export interface WriteToolDetails {
|
|
23
|
+
/** Whether the file was formatted */
|
|
24
|
+
wasFormatted: boolean;
|
|
25
|
+
/** Format result (if available) */
|
|
26
|
+
formatResult?: FileFormatResult;
|
|
27
|
+
/** Whether LSP diagnostics were retrieved */
|
|
28
|
+
hasDiagnostics: boolean;
|
|
29
|
+
/** Diagnostic result (if available) */
|
|
30
|
+
diagnostics?: FileDiagnosticsResult;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function createWriteTool(
|
|
34
|
+
cwd: string,
|
|
35
|
+
options: WriteToolOptions = {},
|
|
36
|
+
): AgentTool<typeof writeSchema, WriteToolDetails> {
|
|
13
37
|
return {
|
|
14
38
|
name: "write",
|
|
15
39
|
label: "Write",
|
|
@@ -30,7 +54,7 @@ Usage:
|
|
|
30
54
|
const absolutePath = resolveToCwd(path, cwd);
|
|
31
55
|
const dir = dirname(absolutePath);
|
|
32
56
|
|
|
33
|
-
return new Promise<{ content: Array<{ type: "text"; text: string }>; details:
|
|
57
|
+
return new Promise<{ content: Array<{ type: "text"; text: string }>; details: WriteToolDetails }>(
|
|
34
58
|
(resolve, reject) => {
|
|
35
59
|
// Check if already aborted
|
|
36
60
|
if (signal?.aborted) {
|
|
@@ -74,9 +98,48 @@ Usage:
|
|
|
74
98
|
signal.removeEventListener("abort", onAbort);
|
|
75
99
|
}
|
|
76
100
|
|
|
101
|
+
// Format file if callback provided (before diagnostics)
|
|
102
|
+
let formatResult: FileFormatResult | undefined;
|
|
103
|
+
if (options.formatOnWrite) {
|
|
104
|
+
try {
|
|
105
|
+
formatResult = await options.formatOnWrite(absolutePath);
|
|
106
|
+
} catch {
|
|
107
|
+
// Ignore formatting errors - don't fail the write
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Get LSP diagnostics if callback provided (after formatting)
|
|
112
|
+
let diagnosticsResult: FileDiagnosticsResult | undefined;
|
|
113
|
+
if (options.getDiagnostics) {
|
|
114
|
+
try {
|
|
115
|
+
diagnosticsResult = await options.getDiagnostics(absolutePath);
|
|
116
|
+
} catch {
|
|
117
|
+
// Ignore diagnostics errors - don't fail the write
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Build result text
|
|
122
|
+
let resultText = `Successfully wrote ${content.length} bytes to ${path}`;
|
|
123
|
+
|
|
124
|
+
// Note if file was formatted
|
|
125
|
+
if (formatResult?.formatted) {
|
|
126
|
+
resultText += ` (formatted by ${formatResult.serverName})`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Append diagnostics if available and there are issues
|
|
130
|
+
if (diagnosticsResult?.available && diagnosticsResult.diagnostics.length > 0) {
|
|
131
|
+
resultText += `\n\nLSP Diagnostics (${diagnosticsResult.summary}):\n`;
|
|
132
|
+
resultText += diagnosticsResult.diagnostics.map((d) => ` ${d}`).join("\n");
|
|
133
|
+
}
|
|
134
|
+
|
|
77
135
|
resolve({
|
|
78
|
-
content: [{ type: "text", text:
|
|
79
|
-
details:
|
|
136
|
+
content: [{ type: "text", text: resultText }],
|
|
137
|
+
details: {
|
|
138
|
+
wasFormatted: formatResult?.formatted ?? false,
|
|
139
|
+
formatResult,
|
|
140
|
+
hasDiagnostics: diagnosticsResult?.available ?? false,
|
|
141
|
+
diagnostics: diagnosticsResult,
|
|
142
|
+
},
|
|
80
143
|
});
|
|
81
144
|
} catch (error: any) {
|
|
82
145
|
// Clean up abort handler
|
package/src/index.ts
CHANGED
|
@@ -10,9 +10,9 @@ export {
|
|
|
10
10
|
type ModelCycleResult,
|
|
11
11
|
type PromptOptions,
|
|
12
12
|
type SessionStats,
|
|
13
|
-
} from "./core/agent-session
|
|
13
|
+
} from "./core/agent-session";
|
|
14
14
|
// Auth and model registry
|
|
15
|
-
export { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from "./core/auth-storage
|
|
15
|
+
export { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from "./core/auth-storage";
|
|
16
16
|
// Compaction
|
|
17
17
|
export {
|
|
18
18
|
type BranchPreparation,
|
|
@@ -35,7 +35,16 @@ export {
|
|
|
35
35
|
prepareBranchEntries,
|
|
36
36
|
serializeConversation,
|
|
37
37
|
shouldCompact,
|
|
38
|
-
} from "./core/compaction/index
|
|
38
|
+
} from "./core/compaction/index";
|
|
39
|
+
// Custom commands
|
|
40
|
+
export type {
|
|
41
|
+
CustomCommand,
|
|
42
|
+
CustomCommandAPI,
|
|
43
|
+
CustomCommandFactory,
|
|
44
|
+
CustomCommandSource,
|
|
45
|
+
CustomCommandsLoadResult,
|
|
46
|
+
LoadedCustomCommand,
|
|
47
|
+
} from "./core/custom-commands/types";
|
|
39
48
|
// Custom tools
|
|
40
49
|
export type {
|
|
41
50
|
AgentToolUpdateCallback,
|
|
@@ -49,9 +58,9 @@ export type {
|
|
|
49
58
|
ExecResult,
|
|
50
59
|
LoadedCustomTool,
|
|
51
60
|
RenderResultOptions,
|
|
52
|
-
} from "./core/custom-tools/index
|
|
53
|
-
export { discoverAndLoadCustomTools, loadCustomTools } from "./core/custom-tools/index
|
|
54
|
-
export type * from "./core/hooks/index
|
|
61
|
+
} from "./core/custom-tools/index";
|
|
62
|
+
export { discoverAndLoadCustomTools, loadCustomTools } from "./core/custom-tools/index";
|
|
63
|
+
export type * from "./core/hooks/index";
|
|
55
64
|
// Hook system types and type guards
|
|
56
65
|
export {
|
|
57
66
|
isBashToolResult,
|
|
@@ -61,9 +70,11 @@ export {
|
|
|
61
70
|
isLsToolResult,
|
|
62
71
|
isReadToolResult,
|
|
63
72
|
isWriteToolResult,
|
|
64
|
-
} from "./core/hooks/index
|
|
65
|
-
|
|
66
|
-
export {
|
|
73
|
+
} from "./core/hooks/index";
|
|
74
|
+
// Logging
|
|
75
|
+
export { type Logger, logger } from "./core/logger";
|
|
76
|
+
export { convertToLlm } from "./core/messages";
|
|
77
|
+
export { ModelRegistry } from "./core/model-registry";
|
|
67
78
|
// SDK for programmatic usage
|
|
68
79
|
export {
|
|
69
80
|
type BuildSystemPromptOptions,
|
|
@@ -98,7 +109,7 @@ export {
|
|
|
98
109
|
loadSettings,
|
|
99
110
|
// Pre-built tools (use process.cwd())
|
|
100
111
|
readOnlyTools,
|
|
101
|
-
} from "./core/sdk
|
|
112
|
+
} from "./core/sdk";
|
|
102
113
|
export {
|
|
103
114
|
type BranchSummaryEntry,
|
|
104
115
|
buildSessionContext,
|
|
@@ -120,14 +131,15 @@ export {
|
|
|
120
131
|
SessionManager,
|
|
121
132
|
type SessionMessageEntry,
|
|
122
133
|
type ThinkingLevelChangeEntry,
|
|
123
|
-
} from "./core/session-manager
|
|
134
|
+
} from "./core/session-manager";
|
|
124
135
|
export {
|
|
125
136
|
type CompactionSettings,
|
|
137
|
+
type LspSettings,
|
|
126
138
|
type RetrySettings,
|
|
127
139
|
type Settings,
|
|
128
140
|
SettingsManager,
|
|
129
141
|
type SkillsSettings,
|
|
130
|
-
} from "./core/settings-manager
|
|
142
|
+
} from "./core/settings-manager";
|
|
131
143
|
// Skills
|
|
132
144
|
export {
|
|
133
145
|
formatSkillsForPrompt,
|
|
@@ -138,11 +150,12 @@ export {
|
|
|
138
150
|
type Skill,
|
|
139
151
|
type SkillFrontmatter,
|
|
140
152
|
type SkillWarning,
|
|
141
|
-
} from "./core/skills
|
|
153
|
+
} from "./core/skills";
|
|
142
154
|
// Tools
|
|
143
155
|
export {
|
|
144
156
|
type BashToolDetails,
|
|
145
157
|
bashTool,
|
|
158
|
+
type CodingToolsOptions,
|
|
146
159
|
codingTools,
|
|
147
160
|
editTool,
|
|
148
161
|
type FindToolDetails,
|
|
@@ -154,14 +167,17 @@ export {
|
|
|
154
167
|
type ReadToolDetails,
|
|
155
168
|
readTool,
|
|
156
169
|
type TruncationResult,
|
|
170
|
+
type WriteToolDetails,
|
|
171
|
+
type WriteToolOptions,
|
|
157
172
|
writeTool,
|
|
158
|
-
} from "./core/tools/index
|
|
173
|
+
} from "./core/tools/index";
|
|
174
|
+
export type { FileDiagnosticsResult } from "./core/tools/lsp/index";
|
|
159
175
|
// Main entry point
|
|
160
|
-
export { main } from "./main
|
|
176
|
+
export { main } from "./main";
|
|
161
177
|
// UI components for hooks and custom tools
|
|
162
|
-
export { BorderedLoader } from "./modes/interactive/components/bordered-loader
|
|
178
|
+
export { BorderedLoader } from "./modes/interactive/components/bordered-loader";
|
|
163
179
|
// Theme utilities for custom tools
|
|
164
|
-
export { getMarkdownTheme } from "./modes/interactive/theme/theme
|
|
180
|
+
export { getMarkdownTheme } from "./modes/interactive/theme/theme";
|
|
165
181
|
|
|
166
182
|
// TypeBox helper for string enums (convenience for custom tools)
|
|
167
183
|
import { type TSchema, Type } from "@sinclair/typebox";
|
package/src/main.ts
CHANGED
|
@@ -5,33 +5,33 @@
|
|
|
5
5
|
* createAgentSession() options. The SDK does the heavy lifting.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
8
10
|
import { type ImageContent, supportsXhigh } from "@oh-my-pi/pi-ai";
|
|
9
11
|
import chalk from "chalk";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import
|
|
19
|
-
import type {
|
|
20
|
-
import {
|
|
21
|
-
import type
|
|
22
|
-
import type
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import { getChangelogPath, getNewEntries, parseChangelog } from "./utils/changelog.js";
|
|
34
|
-
import { ensureTool } from "./utils/tools-manager.js";
|
|
12
|
+
import { type Args, parseArgs, printHelp } from "./cli/args";
|
|
13
|
+
import { processFileArguments } from "./cli/file-processor";
|
|
14
|
+
import { listModels } from "./cli/list-models";
|
|
15
|
+
import { parsePluginArgs, printPluginHelp, runPluginCommand } from "./cli/plugin-cli";
|
|
16
|
+
import { selectSession } from "./cli/session-picker";
|
|
17
|
+
import { CONFIG_DIR_NAME, getAgentDir, getModelsPath, VERSION } from "./config";
|
|
18
|
+
import type { AgentSession } from "./core/agent-session";
|
|
19
|
+
import type { LoadedCustomTool } from "./core/custom-tools/index";
|
|
20
|
+
import { exportFromFile } from "./core/export-html/index";
|
|
21
|
+
import type { HookUIContext } from "./core/index";
|
|
22
|
+
import type { ModelRegistry } from "./core/model-registry";
|
|
23
|
+
import { parseModelPattern, resolveModelScope, type ScopedModel } from "./core/model-resolver";
|
|
24
|
+
import { type CreateAgentSessionOptions, createAgentSession, discoverAuthStorage, discoverModels } from "./core/sdk";
|
|
25
|
+
import { SessionManager } from "./core/session-manager";
|
|
26
|
+
import { SettingsManager } from "./core/settings-manager";
|
|
27
|
+
import { resolvePromptInput } from "./core/system-prompt";
|
|
28
|
+
import { printTimings, time } from "./core/timings";
|
|
29
|
+
import { allTools } from "./core/tools/index";
|
|
30
|
+
import { runMigrations } from "./migrations";
|
|
31
|
+
import { InteractiveMode, installTerminalCrashHandlers, runPrintMode, runRpcMode } from "./modes/index";
|
|
32
|
+
import { initTheme, stopThemeWatcher } from "./modes/interactive/theme/theme";
|
|
33
|
+
import { getChangelogPath, getNewEntries, parseChangelog } from "./utils/changelog";
|
|
34
|
+
import { ensureTool } from "./utils/tools-manager";
|
|
35
35
|
|
|
36
36
|
async function checkForNewVersion(currentVersion: string): Promise<string | undefined> {
|
|
37
37
|
try {
|
|
@@ -62,11 +62,20 @@ async function runInteractiveMode(
|
|
|
62
62
|
initialMessages: string[],
|
|
63
63
|
customTools: LoadedCustomTool[],
|
|
64
64
|
setToolUIContext: (uiContext: HookUIContext, hasUI: boolean) => void,
|
|
65
|
+
lspServers: Array<{ name: string; status: "ready" | "error"; fileTypes: string[] }> | undefined,
|
|
65
66
|
initialMessage?: string,
|
|
66
67
|
initialImages?: ImageContent[],
|
|
67
68
|
fdPath: string | undefined = undefined,
|
|
68
69
|
): Promise<void> {
|
|
69
|
-
const mode = new InteractiveMode(
|
|
70
|
+
const mode = new InteractiveMode(
|
|
71
|
+
session,
|
|
72
|
+
version,
|
|
73
|
+
changelogMarkdown,
|
|
74
|
+
customTools,
|
|
75
|
+
setToolUIContext,
|
|
76
|
+
lspServers,
|
|
77
|
+
fdPath,
|
|
78
|
+
);
|
|
70
79
|
|
|
71
80
|
await mode.init();
|
|
72
81
|
|
|
@@ -204,12 +213,12 @@ function discoverSystemPromptFile(): string | undefined {
|
|
|
204
213
|
return undefined;
|
|
205
214
|
}
|
|
206
215
|
|
|
207
|
-
function buildSessionOptions(
|
|
216
|
+
async function buildSessionOptions(
|
|
208
217
|
parsed: Args,
|
|
209
218
|
scopedModels: ScopedModel[],
|
|
210
219
|
sessionManager: SessionManager | undefined,
|
|
211
220
|
modelRegistry: ModelRegistry,
|
|
212
|
-
): CreateAgentSessionOptions {
|
|
221
|
+
): Promise<CreateAgentSessionOptions> {
|
|
213
222
|
const options: CreateAgentSessionOptions = {};
|
|
214
223
|
|
|
215
224
|
// Auto-discover SYSTEM.md if no CLI system prompt provided
|
|
@@ -221,11 +230,15 @@ function buildSessionOptions(
|
|
|
221
230
|
options.sessionManager = sessionManager;
|
|
222
231
|
}
|
|
223
232
|
|
|
224
|
-
// Model from CLI
|
|
225
|
-
if (parsed.
|
|
226
|
-
const
|
|
233
|
+
// Model from CLI (--model) - uses same fuzzy matching as --models
|
|
234
|
+
if (parsed.model) {
|
|
235
|
+
const available = await modelRegistry.getAvailable();
|
|
236
|
+
const { model, warning } = parseModelPattern(parsed.model, available);
|
|
237
|
+
if (warning) {
|
|
238
|
+
console.warn(chalk.yellow(`Warning: ${warning}`));
|
|
239
|
+
}
|
|
227
240
|
if (!model) {
|
|
228
|
-
console.error(chalk.red(`Model ${parsed.
|
|
241
|
+
console.error(chalk.red(`Model "${parsed.model}" not found`));
|
|
229
242
|
process.exit(1);
|
|
230
243
|
}
|
|
231
244
|
options.model = model;
|
|
@@ -260,6 +273,7 @@ function buildSessionOptions(
|
|
|
260
273
|
// Tools
|
|
261
274
|
if (parsed.tools) {
|
|
262
275
|
options.tools = parsed.tools.map((name) => allTools[name]);
|
|
276
|
+
options.explicitTools = parsed.tools;
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
// Skills
|
|
@@ -347,6 +361,17 @@ export async function main(args: string[]) {
|
|
|
347
361
|
|
|
348
362
|
const settingsManager = SettingsManager.create(cwd);
|
|
349
363
|
time("SettingsManager.create");
|
|
364
|
+
|
|
365
|
+
// Apply model role overrides from CLI args or env vars (ephemeral, not persisted)
|
|
366
|
+
const smolModel = parsed.smol ?? process.env.PI_SMOL_MODEL;
|
|
367
|
+
const slowModel = parsed.slow ?? process.env.PI_SLOW_MODEL;
|
|
368
|
+
if (smolModel || slowModel) {
|
|
369
|
+
const roleOverrides: Record<string, string> = {};
|
|
370
|
+
if (smolModel) roleOverrides.smol = smolModel;
|
|
371
|
+
if (slowModel) roleOverrides.slow = slowModel;
|
|
372
|
+
settingsManager.applyOverrides({ modelRoles: roleOverrides });
|
|
373
|
+
}
|
|
374
|
+
|
|
350
375
|
initTheme(settingsManager.getTheme(), isInteractive);
|
|
351
376
|
time("initTheme");
|
|
352
377
|
|
|
@@ -378,7 +403,7 @@ export async function main(args: string[]) {
|
|
|
378
403
|
sessionManager = SessionManager.open(selectedPath);
|
|
379
404
|
}
|
|
380
405
|
|
|
381
|
-
const sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry);
|
|
406
|
+
const sessionOptions = await buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry);
|
|
382
407
|
sessionOptions.authStorage = authStorage;
|
|
383
408
|
sessionOptions.modelRegistry = modelRegistry;
|
|
384
409
|
sessionOptions.hasUI = isInteractive;
|
|
@@ -393,7 +418,7 @@ export async function main(args: string[]) {
|
|
|
393
418
|
}
|
|
394
419
|
|
|
395
420
|
time("buildSessionOptions");
|
|
396
|
-
const { session, customToolsResult, modelFallbackMessage } = await createAgentSession(sessionOptions);
|
|
421
|
+
const { session, customToolsResult, modelFallbackMessage, lspServers } = await createAgentSession(sessionOptions);
|
|
397
422
|
time("createAgentSession");
|
|
398
423
|
|
|
399
424
|
if (!isInteractive && !session.model) {
|
|
@@ -449,6 +474,7 @@ export async function main(args: string[]) {
|
|
|
449
474
|
parsed.messages,
|
|
450
475
|
customToolsResult.tools,
|
|
451
476
|
customToolsResult.setUIContext,
|
|
477
|
+
lspServers,
|
|
452
478
|
initialMessage,
|
|
453
479
|
initialImages,
|
|
454
480
|
fdPath,
|
package/src/migrations.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* One-time migrations that run on startup.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
6
|
-
import { dirname, join } from "path";
|
|
7
|
-
import { getAgentDir } from "./config
|
|
5
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { getAgentDir } from "./config";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Migrate legacy oauth.json and settings.json apiKeys to auth.json.
|
package/src/modes/index.ts
CHANGED
|
@@ -36,8 +36,8 @@ export function installTerminalCrashHandlers(): void {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export { InteractiveMode } from "./interactive/interactive-mode
|
|
40
|
-
export { runPrintMode } from "./print-mode
|
|
41
|
-
export { type ModelInfo, RpcClient, type RpcClientOptions, type RpcEventListener } from "./rpc/rpc-client
|
|
42
|
-
export { runRpcMode } from "./rpc/rpc-mode
|
|
43
|
-
export type { RpcCommand, RpcResponse, RpcSessionState } from "./rpc/rpc-types
|
|
39
|
+
export { InteractiveMode } from "./interactive/interactive-mode";
|
|
40
|
+
export { runPrintMode } from "./print-mode";
|
|
41
|
+
export { type ModelInfo, RpcClient, type RpcClientOptions, type RpcEventListener } from "./rpc/rpc-client";
|
|
42
|
+
export { runRpcMode } from "./rpc/rpc-mode";
|
|
43
|
+
export type { RpcCommand, RpcResponse, RpcSessionState } from "./rpc/rpc-types";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AssistantMessage } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import { Container, Markdown, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
3
|
-
import { getMarkdownTheme, theme } from "../theme/theme
|
|
3
|
+
import { getMarkdownTheme, theme } from "../theme/theme";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Component that renders a complete assistant message
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
DEFAULT_MAX_LINES,
|
|
10
10
|
type TruncationResult,
|
|
11
11
|
truncateTail,
|
|
12
|
-
} from "../../../core/tools/truncate
|
|
13
|
-
import { theme } from "../theme/theme
|
|
14
|
-
import { DynamicBorder } from "./dynamic-border
|
|
15
|
-
import { truncateToVisualLines } from "./visual-truncate
|
|
12
|
+
} from "../../../core/tools/truncate";
|
|
13
|
+
import { theme } from "../theme/theme";
|
|
14
|
+
import { DynamicBorder } from "./dynamic-border";
|
|
15
|
+
import { truncateToVisualLines } from "./visual-truncate";
|
|
16
16
|
|
|
17
17
|
// Preview line limit when not expanded (matches tool execution behavior)
|
|
18
18
|
const PREVIEW_LINES = 20;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CancellableLoader, Container, Spacer, Text, type TUI } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import type { Theme } from "../theme/theme
|
|
3
|
-
import { DynamicBorder } from "./dynamic-border
|
|
2
|
+
import type { Theme } from "../theme/theme";
|
|
3
|
+
import { DynamicBorder } from "./dynamic-border";
|
|
4
4
|
|
|
5
5
|
/** Loader wrapped with borders for hook UI */
|
|
6
6
|
export class BorderedLoader extends Container {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Box, Markdown, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import type { BranchSummaryMessage } from "../../../core/messages
|
|
3
|
-
import { getMarkdownTheme, theme } from "../theme/theme
|
|
2
|
+
import type { BranchSummaryMessage } from "../../../core/messages";
|
|
3
|
+
import { getMarkdownTheme, theme } from "../theme/theme";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Component that renders a branch summary message with collapsed/expanded state.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Box, Markdown, Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import type { CompactionSummaryMessage } from "../../../core/messages
|
|
3
|
-
import { getMarkdownTheme, theme } from "../theme/theme
|
|
2
|
+
import type { CompactionSummaryMessage } from "../../../core/messages";
|
|
3
|
+
import { getMarkdownTheme, theme } from "../theme/theme";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Component that renders a compaction message with collapsed/expanded state.
|