@oh-my-pi/pi-coding-agent 1.341.0 → 2.1.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 +86 -0
- package/README.md +1 -1
- package/examples/custom-tools/subagent/index.ts +1 -1
- package/package.json +10 -9
- package/src/bun-imports.d.ts +16 -0
- package/src/cli/args.ts +5 -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/update-cli.ts +273 -0
- package/src/cli.ts +1 -1
- package/src/config.ts +23 -75
- package/src/core/agent-session.ts +158 -16
- package/src/core/auth-storage.ts +2 -3
- 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 +38 -123
- package/src/core/export-html/template.css +0 -7
- package/src/core/export-html/template.html +3 -4
- package/src/core/export-html/template.macro.ts +24 -0
- 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 +2 -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 +77 -35
- package/src/core/session-manager.ts +6 -6
- package/src/core/settings-manager.ts +16 -3
- 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 +2 -2
- package/src/core/tools/bash.ts +32 -155
- package/src/core/tools/context.ts +2 -2
- package/src/core/tools/edit-diff.ts +3 -3
- package/src/core/tools/edit.ts +18 -5
- 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 +3 -3
- package/src/core/tools/index.ts +48 -34
- package/src/core/tools/ls.ts +4 -4
- package/src/core/tools/lsp/client.ts +161 -90
- package/src/core/tools/lsp/config.ts +1 -1
- package/src/core/tools/lsp/edits.ts +2 -2
- package/src/core/tools/lsp/index.ts +15 -13
- package/src/core/tools/lsp/render.ts +2 -2
- package/src/core/tools/lsp/rust-analyzer.ts +3 -3
- 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 +22 -38
- package/src/core/tools/task/bundled-agents/reviewer.md +52 -37
- package/src/core/tools/task/commands.ts +31 -10
- 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 +30 -20
- 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 +4 -4
- package/src/index.ts +29 -18
- package/src/main.ts +50 -33
- 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 +281 -59
- 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 +4 -4
- package/src/modes/interactive/components/settings-defs.ts +1 -1
- package/src/modes/interactive/components/settings-selector.ts +5 -5
- 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 +26 -8
- package/src/modes/interactive/components/tree-selector.ts +3 -3
- 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 +2 -2
- package/src/modes/interactive/interactive-mode.ts +86 -42
- package/src/modes/interactive/theme/theme.ts +15 -17
- package/src/modes/print-mode.ts +4 -3
- package/src/modes/rpc/rpc-client.ts +4 -4
- package/src/modes/rpc/rpc-mode.ts +22 -12
- 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
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized file logger for pi.
|
|
3
|
+
*
|
|
4
|
+
* Logs to ~/.pi/logs/ with size-based rotation, supporting concurrent pi instances.
|
|
5
|
+
* Each log entry includes process.pid for traceability.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import winston from "winston";
|
|
12
|
+
import DailyRotateFile from "winston-daily-rotate-file";
|
|
13
|
+
import { CONFIG_DIR_NAME } from "../config";
|
|
14
|
+
|
|
15
|
+
/** Get the logs directory (~/.pi/logs/) */
|
|
16
|
+
function getLogsDir(): string {
|
|
17
|
+
return join(homedir(), CONFIG_DIR_NAME, "logs");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Ensure logs directory exists */
|
|
21
|
+
function ensureLogsDir(): string {
|
|
22
|
+
const logsDir = getLogsDir();
|
|
23
|
+
if (!existsSync(logsDir)) {
|
|
24
|
+
mkdirSync(logsDir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
return logsDir;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Custom format that includes pid and flattens metadata */
|
|
30
|
+
const logFormat = winston.format.combine(
|
|
31
|
+
winston.format.timestamp({ format: "YYYY-MM-DDTHH:mm:ss.SSSZ" }),
|
|
32
|
+
winston.format.printf(({ timestamp, level, message, ...meta }) => {
|
|
33
|
+
const entry: Record<string, unknown> = {
|
|
34
|
+
timestamp,
|
|
35
|
+
level,
|
|
36
|
+
pid: process.pid,
|
|
37
|
+
message,
|
|
38
|
+
};
|
|
39
|
+
// Flatten metadata into entry
|
|
40
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
41
|
+
if (key !== "level" && key !== "timestamp" && key !== "message") {
|
|
42
|
+
entry[key] = value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return JSON.stringify(entry);
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
/** Size-based rotating file transport */
|
|
50
|
+
const fileTransport = new DailyRotateFile({
|
|
51
|
+
dirname: ensureLogsDir(),
|
|
52
|
+
filename: "pi.%DATE%.log",
|
|
53
|
+
datePattern: "YYYY-MM-DD",
|
|
54
|
+
maxSize: "10m",
|
|
55
|
+
maxFiles: 5,
|
|
56
|
+
zippedArchive: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/** The winston logger instance */
|
|
60
|
+
const winstonLogger = winston.createLogger({
|
|
61
|
+
level: "debug",
|
|
62
|
+
format: logFormat,
|
|
63
|
+
transports: [fileTransport],
|
|
64
|
+
// Don't exit on error - logging failures shouldn't crash the app
|
|
65
|
+
exitOnError: false,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/** Logger type exposed to plugins and internal code */
|
|
69
|
+
export interface Logger {
|
|
70
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
71
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
72
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Centralized logger for pi.
|
|
77
|
+
*
|
|
78
|
+
* Logs to ~/.pi/logs/pi.YYYY-MM-DD.log with size-based rotation.
|
|
79
|
+
* Safe for concurrent access from multiple pi instances.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* import { logger } from "../core/logger";
|
|
84
|
+
*
|
|
85
|
+
* logger.error("MCP request failed", { url, method });
|
|
86
|
+
* logger.warn("Theme file invalid, using fallback", { path });
|
|
87
|
+
* logger.debug("LSP fallback triggered", { reason });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export const logger: Logger = {
|
|
91
|
+
error(message: string, context?: Record<string, unknown>): void {
|
|
92
|
+
try {
|
|
93
|
+
winstonLogger.error(message, context);
|
|
94
|
+
} catch {
|
|
95
|
+
// Silently ignore logging failures
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
warn(message: string, context?: Record<string, unknown>): void {
|
|
99
|
+
try {
|
|
100
|
+
winstonLogger.warn(message, context);
|
|
101
|
+
} catch {
|
|
102
|
+
// Silently ignore logging failures
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
debug(message: string, context?: Record<string, unknown>): void {
|
|
106
|
+
try {
|
|
107
|
+
winstonLogger.debug(message, context);
|
|
108
|
+
} catch {
|
|
109
|
+
// Silently ignore logging failures
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
};
|
package/src/core/mcp/client.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Handles connection initialization, tool listing, and tool calling.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { createHttpTransport } from "./transports/http
|
|
8
|
-
import { createStdioTransport } from "./transports/stdio
|
|
7
|
+
import { createHttpTransport } from "./transports/http";
|
|
8
|
+
import { createStdioTransport } from "./transports/stdio";
|
|
9
9
|
import type {
|
|
10
10
|
MCPHttpServerConfig,
|
|
11
11
|
MCPInitializeParams,
|
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
MCPToolDefinition,
|
|
21
21
|
MCPToolsListResult,
|
|
22
22
|
MCPTransport,
|
|
23
|
-
} from "./types
|
|
23
|
+
} from "./types";
|
|
24
24
|
|
|
25
25
|
/** MCP protocol version we support */
|
|
26
26
|
const PROTOCOL_VERSION = "2025-03-26";
|
package/src/core/mcp/config.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
10
|
import { join } from "node:path";
|
|
11
|
-
import type { MCPConfigFile, MCPServerConfig } from "./types
|
|
11
|
+
import type { MCPConfigFile, MCPServerConfig } from "./types";
|
|
12
12
|
|
|
13
13
|
/** Environment variable expansion pattern: ${VAR} or ${VAR:-default} */
|
|
14
14
|
const ENV_VAR_PATTERN = /\$\{([^}:]+)(?::-([^}]*))?\}/g;
|
package/src/core/mcp/index.ts
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
// Client
|
|
9
|
-
export { callTool, connectToServer, disconnectServer, listTools, serverSupportsTools } from "./client
|
|
9
|
+
export { callTool, connectToServer, disconnectServer, listTools, serverSupportsTools } from "./client";
|
|
10
10
|
|
|
11
11
|
// Config
|
|
12
|
-
export type { ExaFilterResult, LoadMCPConfigsOptions, LoadMCPConfigsResult } from "./config
|
|
12
|
+
export type { ExaFilterResult, LoadMCPConfigsOptions, LoadMCPConfigsResult } from "./config";
|
|
13
13
|
export {
|
|
14
14
|
expandEnvVars,
|
|
15
15
|
extractExaApiKey,
|
|
@@ -20,19 +20,19 @@ export {
|
|
|
20
20
|
loadMCPConfigFile,
|
|
21
21
|
mergeMCPConfigs,
|
|
22
22
|
validateServerConfig,
|
|
23
|
-
} from "./config
|
|
23
|
+
} from "./config";
|
|
24
24
|
// Loader (for SDK integration)
|
|
25
|
-
export type { MCPToolsLoadOptions, MCPToolsLoadResult } from "./loader
|
|
26
|
-
export { discoverAndLoadMCPTools } from "./loader
|
|
25
|
+
export type { MCPToolsLoadOptions, MCPToolsLoadResult } from "./loader";
|
|
26
|
+
export { discoverAndLoadMCPTools } from "./loader";
|
|
27
27
|
// Manager
|
|
28
|
-
export type { MCPDiscoverOptions, MCPLoadResult } from "./manager
|
|
29
|
-
export { createMCPManager, MCPManager } from "./manager
|
|
28
|
+
export type { MCPDiscoverOptions, MCPLoadResult } from "./manager";
|
|
29
|
+
export { createMCPManager, MCPManager } from "./manager";
|
|
30
30
|
// Tool bridge
|
|
31
|
-
export type { MCPToolDetails } from "./tool-bridge
|
|
32
|
-
export { createMCPTool, createMCPToolName, createMCPTools, parseMCPToolName } from "./tool-bridge
|
|
31
|
+
export type { MCPToolDetails } from "./tool-bridge";
|
|
32
|
+
export { createMCPTool, createMCPToolName, createMCPTools, parseMCPToolName } from "./tool-bridge";
|
|
33
33
|
// Transports
|
|
34
|
-
export { createHttpTransport, HttpTransport } from "./transports/http
|
|
35
|
-
export { createStdioTransport, StdioTransport } from "./transports/stdio
|
|
34
|
+
export { createHttpTransport, HttpTransport } from "./transports/http";
|
|
35
|
+
export { createStdioTransport, StdioTransport } from "./transports/stdio";
|
|
36
36
|
// Types
|
|
37
37
|
export type {
|
|
38
38
|
MCPConfigFile,
|
|
@@ -46,4 +46,4 @@ export type {
|
|
|
46
46
|
MCPToolDefinition,
|
|
47
47
|
MCPToolWithServer,
|
|
48
48
|
MCPTransport,
|
|
49
|
-
} from "./types
|
|
49
|
+
} from "./types";
|
package/src/core/mcp/loader.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Integrates MCP tool discovery with the custom tools system.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { LoadedCustomTool } from "../custom-tools/types
|
|
8
|
-
import { type MCPLoadResult, MCPManager } from "./manager
|
|
7
|
+
import type { LoadedCustomTool } from "../custom-tools/types";
|
|
8
|
+
import { type MCPLoadResult, MCPManager } from "./manager";
|
|
9
9
|
|
|
10
10
|
/** Result from loading MCP tools */
|
|
11
11
|
export interface MCPToolsLoadResult {
|
package/src/core/mcp/manager.ts
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { TSchema } from "@sinclair/typebox";
|
|
9
|
-
import type { CustomTool } from "../custom-tools/types
|
|
10
|
-
import { connectToServer, disconnectServer, listTools } from "./client
|
|
11
|
-
import { type LoadMCPConfigsOptions, loadAllMCPConfigs, validateServerConfig } from "./config
|
|
12
|
-
import type { MCPToolDetails } from "./tool-bridge
|
|
13
|
-
import { createMCPTools } from "./tool-bridge
|
|
14
|
-
import type { MCPServerConfig, MCPServerConnection } from "./types
|
|
9
|
+
import type { CustomTool } from "../custom-tools/types";
|
|
10
|
+
import { connectToServer, disconnectServer, listTools } from "./client";
|
|
11
|
+
import { type LoadMCPConfigsOptions, loadAllMCPConfigs, validateServerConfig } from "./config";
|
|
12
|
+
import type { MCPToolDetails } from "./tool-bridge";
|
|
13
|
+
import { createMCPTools } from "./tool-bridge";
|
|
14
|
+
import type { MCPServerConfig, MCPServerConnection } from "./types";
|
|
15
15
|
|
|
16
16
|
/** Result of loading MCP tools */
|
|
17
17
|
export interface MCPLoadResult {
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { TSchema } from "@sinclair/typebox";
|
|
8
|
-
import type { CustomTool, CustomToolResult } from "../custom-tools/types
|
|
9
|
-
import { callTool } from "./client
|
|
10
|
-
import type { MCPContent, MCPServerConnection, MCPToolDefinition } from "./types
|
|
8
|
+
import type { CustomTool, CustomToolResult } from "../custom-tools/types";
|
|
9
|
+
import { callTool } from "./client";
|
|
10
|
+
import type { MCPContent, MCPServerConnection, MCPToolDefinition } from "./types";
|
|
11
11
|
|
|
12
12
|
/** Details included in MCP tool results for rendering */
|
|
13
13
|
export interface MCPToolDetails {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Based on MCP spec 2025-03-26.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { JsonRpcResponse, MCPHttpServerConfig, MCPSseServerConfig, MCPTransport } from "../types
|
|
8
|
+
import type { JsonRpcResponse, MCPHttpServerConfig, MCPSseServerConfig, MCPTransport } from "../types";
|
|
9
9
|
|
|
10
10
|
/** Generate unique request ID */
|
|
11
11
|
function generateId(): string {
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* MCP transport exports.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export { createHttpTransport, HttpTransport } from "./http
|
|
6
|
-
export { createStdioTransport, StdioTransport } from "./stdio
|
|
5
|
+
export { createHttpTransport, HttpTransport } from "./http";
|
|
6
|
+
export { createStdioTransport, StdioTransport } from "./stdio";
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { type Subprocess, spawn } from "bun";
|
|
9
|
-
import type { JsonRpcResponse, MCPStdioServerConfig, MCPTransport } from "../types
|
|
9
|
+
import type { JsonRpcResponse, MCPStdioServerConfig, MCPTransport } from "../types";
|
|
10
10
|
|
|
11
11
|
/** Generate unique request ID */
|
|
12
12
|
function generateId(): string {
|
package/src/core/messages.ts
CHANGED
|
@@ -64,6 +64,19 @@ export interface CompactionSummaryMessage {
|
|
|
64
64
|
timestamp: number;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Message type for auto-read file mentions via @filepath syntax.
|
|
69
|
+
*/
|
|
70
|
+
export interface FileMentionMessage {
|
|
71
|
+
role: "fileMention";
|
|
72
|
+
files: Array<{
|
|
73
|
+
path: string;
|
|
74
|
+
content: string;
|
|
75
|
+
lineCount: number;
|
|
76
|
+
}>;
|
|
77
|
+
timestamp: number;
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
// Extend CustomAgentMessages via declaration merging
|
|
68
81
|
declare module "@oh-my-pi/pi-agent-core" {
|
|
69
82
|
interface CustomAgentMessages {
|
|
@@ -71,6 +84,7 @@ declare module "@oh-my-pi/pi-agent-core" {
|
|
|
71
84
|
hookMessage: HookMessage;
|
|
72
85
|
branchSummary: BranchSummaryMessage;
|
|
73
86
|
compactionSummary: CompactionSummaryMessage;
|
|
87
|
+
fileMention: FileMentionMessage;
|
|
74
88
|
}
|
|
75
89
|
}
|
|
76
90
|
|
|
@@ -175,6 +189,14 @@ export function convertToLlm(messages: AgentMessage[]): Message[] {
|
|
|
175
189
|
],
|
|
176
190
|
timestamp: m.timestamp,
|
|
177
191
|
};
|
|
192
|
+
case "fileMention": {
|
|
193
|
+
const fileContents = m.files.map((f) => `<file path="${f.path}">\n${f.content}\n</file>`).join("\n\n");
|
|
194
|
+
return {
|
|
195
|
+
role: "user",
|
|
196
|
+
content: [{ type: "text" as const, text: `<system-reminder>\n${fileContents}\n</system-reminder>` }],
|
|
197
|
+
timestamp: m.timestamp,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
178
200
|
case "user":
|
|
179
201
|
case "assistant":
|
|
180
202
|
case "toolResult":
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Model registry - manages built-in and custom models, provides API key resolution.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
6
|
import {
|
|
6
7
|
type Api,
|
|
7
8
|
getGitHubCopilotBaseUrl,
|
|
@@ -13,8 +14,7 @@ import {
|
|
|
13
14
|
} from "@oh-my-pi/pi-ai";
|
|
14
15
|
import { type Static, Type } from "@sinclair/typebox";
|
|
15
16
|
import AjvModule from "ajv";
|
|
16
|
-
import {
|
|
17
|
-
import type { AuthStorage } from "./auth-storage.js";
|
|
17
|
+
import type { AuthStorage } from "./auth-storage";
|
|
18
18
|
|
|
19
19
|
const Ajv = (AjvModule as any).default || AjvModule;
|
|
20
20
|
|
|
@@ -6,8 +6,8 @@ import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
|
6
6
|
import { type Api, type KnownProvider, type Model, modelsAreEqual } from "@oh-my-pi/pi-ai";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { minimatch } from "minimatch";
|
|
9
|
-
import { isValidThinkingLevel } from "../cli/args
|
|
10
|
-
import type { ModelRegistry } from "./model-registry
|
|
9
|
+
import { isValidThinkingLevel } from "../cli/args";
|
|
10
|
+
import type { ModelRegistry } from "./model-registry";
|
|
11
11
|
|
|
12
12
|
/** Default model IDs for each known provider */
|
|
13
13
|
export const defaultModelPerProvider: Record<KnownProvider, string> = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Plugin system exports
|
|
2
|
-
export { formatDoctorResults, runDoctorChecks } from "./doctor
|
|
2
|
+
export { formatDoctorResults, runDoctorChecks } from "./doctor";
|
|
3
3
|
export {
|
|
4
4
|
getAllPluginCommandPaths,
|
|
5
5
|
getAllPluginHookPaths,
|
|
@@ -9,16 +9,16 @@ export {
|
|
|
9
9
|
resolvePluginCommandPaths,
|
|
10
10
|
resolvePluginHookPaths,
|
|
11
11
|
resolvePluginToolPaths,
|
|
12
|
-
} from "./loader
|
|
13
|
-
export { PluginManager, parseSettingValue, validateSetting } from "./manager
|
|
14
|
-
export { extractPackageName, formatPluginSpec, parsePluginSpec } from "./parser
|
|
12
|
+
} from "./loader";
|
|
13
|
+
export { PluginManager, parseSettingValue, validateSetting } from "./manager";
|
|
14
|
+
export { extractPackageName, formatPluginSpec, parsePluginSpec } from "./parser";
|
|
15
15
|
export {
|
|
16
16
|
getPluginsDir,
|
|
17
17
|
getPluginsLockfile,
|
|
18
18
|
getPluginsNodeModules,
|
|
19
19
|
getPluginsPackageJson,
|
|
20
20
|
getProjectPluginOverrides,
|
|
21
|
-
} from "./paths
|
|
21
|
+
} from "./paths";
|
|
22
22
|
export type {
|
|
23
23
|
BooleanSetting,
|
|
24
24
|
DoctorCheck,
|
|
@@ -35,4 +35,4 @@ export type {
|
|
|
35
35
|
PluginSettingType,
|
|
36
36
|
ProjectPluginOverrides,
|
|
37
37
|
StringSetting,
|
|
38
|
-
} from "./types
|
|
38
|
+
} from "./types";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { mkdir } from "fs/promises";
|
|
2
|
-
import { join, resolve } from "path";
|
|
3
|
-
import { getAgentDir } from "../../config
|
|
4
|
-
import type { InstalledPlugin } from "./types
|
|
1
|
+
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { getAgentDir } from "../../config";
|
|
4
|
+
import type { InstalledPlugin } from "./types";
|
|
5
5
|
|
|
6
6
|
const PLUGINS_DIR = join(getAgentDir(), "plugins");
|
|
7
7
|
|
|
@@ -5,15 +5,10 @@
|
|
|
5
5
|
* based on manifest entries and enabled features.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { existsSync, readFileSync } from "fs";
|
|
9
|
-
import { join } from "path";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
getPluginsNodeModules,
|
|
13
|
-
getPluginsPackageJson,
|
|
14
|
-
getProjectPluginOverrides,
|
|
15
|
-
} from "./paths.js";
|
|
16
|
-
import type { InstalledPlugin, PluginManifest, PluginRuntimeConfig, ProjectPluginOverrides } from "./types.js";
|
|
8
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { getPluginsLockfile, getPluginsNodeModules, getPluginsPackageJson, getProjectPluginOverrides } from "./paths";
|
|
11
|
+
import type { InstalledPlugin, PluginManifest, PluginRuntimeConfig, ProjectPluginOverrides } from "./types";
|
|
17
12
|
|
|
18
13
|
// =============================================================================
|
|
19
14
|
// Runtime Config Loading
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { existsSync, lstatSync, mkdirSync, readFileSync, symlinkSync, unlinkSync, writeFileSync } from "fs";
|
|
2
|
-
import { join, resolve } from "path";
|
|
3
|
-
import { extractPackageName, parsePluginSpec } from "./parser
|
|
1
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { extractPackageName, parsePluginSpec } from "./parser";
|
|
4
4
|
import {
|
|
5
5
|
getPluginsDir,
|
|
6
6
|
getPluginsLockfile,
|
|
7
7
|
getPluginsNodeModules,
|
|
8
8
|
getPluginsPackageJson,
|
|
9
9
|
getProjectPluginOverrides,
|
|
10
|
-
} from "./paths
|
|
10
|
+
} from "./paths";
|
|
11
11
|
import type {
|
|
12
12
|
DoctorCheck,
|
|
13
13
|
DoctorOptions,
|
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
PluginRuntimeConfig,
|
|
18
18
|
PluginSettingSchema,
|
|
19
19
|
ProjectPluginOverrides,
|
|
20
|
-
} from "./types
|
|
20
|
+
} from "./types";
|
|
21
21
|
|
|
22
22
|
// =============================================================================
|
|
23
23
|
// Validation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { homedir } from "os";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { CONFIG_DIR_NAME } from "../../config
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { CONFIG_DIR_NAME } from "../../config";
|
|
4
4
|
|
|
5
5
|
// =============================================================================
|
|
6
6
|
// Plugin Directory Paths
|
package/src/core/sdk.ts
CHANGED
|
@@ -29,34 +29,38 @@
|
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
+
import { join } from "node:path";
|
|
32
33
|
import { Agent, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
33
34
|
import type { Model } from "@oh-my-pi/pi-ai";
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
35
|
+
import { getAgentDir } from "../config";
|
|
36
|
+
import { AgentSession } from "./agent-session";
|
|
37
|
+
import { AuthStorage } from "./auth-storage";
|
|
38
|
+
import {
|
|
39
|
+
type CustomCommandsLoadResult,
|
|
40
|
+
loadCustomCommands as loadCustomCommandsInternal,
|
|
41
|
+
} from "./custom-commands/index";
|
|
38
42
|
import {
|
|
39
43
|
type CustomToolsLoadResult,
|
|
40
44
|
discoverAndLoadCustomTools,
|
|
41
45
|
type LoadedCustomTool,
|
|
42
46
|
wrapCustomTools,
|
|
43
|
-
} from "./custom-tools/index
|
|
44
|
-
import type { CustomTool } from "./custom-tools/types
|
|
45
|
-
import { discoverAndLoadHooks, HookRunner, type LoadedHook, wrapToolsWithHooks } from "./hooks/index
|
|
46
|
-
import type { HookFactory } from "./hooks/types
|
|
47
|
-
import { discoverAndLoadMCPTools, type MCPManager, type MCPToolsLoadResult } from "./mcp/index
|
|
48
|
-
import { convertToLlm } from "./messages
|
|
49
|
-
import { ModelRegistry } from "./model-registry
|
|
50
|
-
import { SessionManager } from "./session-manager
|
|
51
|
-
import { type Settings, SettingsManager, type SkillsSettings } from "./settings-manager
|
|
52
|
-
import { loadSkills as loadSkillsInternal, type Skill } from "./skills
|
|
53
|
-
import { type FileSlashCommand, loadSlashCommands as loadSlashCommandsInternal } from "./slash-commands
|
|
47
|
+
} from "./custom-tools/index";
|
|
48
|
+
import type { CustomTool } from "./custom-tools/types";
|
|
49
|
+
import { discoverAndLoadHooks, HookRunner, type LoadedHook, wrapToolsWithHooks } from "./hooks/index";
|
|
50
|
+
import type { HookFactory } from "./hooks/types";
|
|
51
|
+
import { discoverAndLoadMCPTools, type MCPManager, type MCPToolsLoadResult } from "./mcp/index";
|
|
52
|
+
import { convertToLlm } from "./messages";
|
|
53
|
+
import { ModelRegistry } from "./model-registry";
|
|
54
|
+
import { SessionManager } from "./session-manager";
|
|
55
|
+
import { type CommandsSettings, type Settings, SettingsManager, type SkillsSettings } from "./settings-manager";
|
|
56
|
+
import { loadSkills as loadSkillsInternal, type Skill } from "./skills";
|
|
57
|
+
import { type FileSlashCommand, loadSlashCommands as loadSlashCommandsInternal } from "./slash-commands";
|
|
54
58
|
import {
|
|
55
59
|
buildSystemPrompt as buildSystemPromptInternal,
|
|
56
60
|
loadProjectContextFiles as loadContextFilesInternal,
|
|
57
|
-
} from "./system-prompt
|
|
58
|
-
import { time } from "./timings
|
|
59
|
-
import { createToolContextStore } from "./tools/context
|
|
61
|
+
} from "./system-prompt";
|
|
62
|
+
import { time } from "./timings";
|
|
63
|
+
import { createToolContextStore } from "./tools/context";
|
|
60
64
|
import {
|
|
61
65
|
allTools,
|
|
62
66
|
applyBashInterception,
|
|
@@ -80,7 +84,7 @@ import {
|
|
|
80
84
|
type Tool,
|
|
81
85
|
warmupLspServers,
|
|
82
86
|
writeTool,
|
|
83
|
-
} from "./tools/index
|
|
87
|
+
} from "./tools/index";
|
|
84
88
|
|
|
85
89
|
// Types
|
|
86
90
|
|
|
@@ -127,6 +131,9 @@ export interface CreateAgentSessionOptions {
|
|
|
127
131
|
/** Enable MCP server discovery from .mcp.json files. Default: true */
|
|
128
132
|
enableMCP?: boolean;
|
|
129
133
|
|
|
134
|
+
/** Tool names explicitly requested (enables disabled-by-default tools) */
|
|
135
|
+
explicitTools?: string[];
|
|
136
|
+
|
|
130
137
|
/** Session manager. Default: SessionManager.create(cwd) */
|
|
131
138
|
sessionManager?: SessionManager;
|
|
132
139
|
|
|
@@ -153,13 +160,14 @@ export interface CreateAgentSessionResult {
|
|
|
153
160
|
|
|
154
161
|
// Re-exports
|
|
155
162
|
|
|
156
|
-
export type {
|
|
157
|
-
export type {
|
|
158
|
-
export type {
|
|
159
|
-
export type {
|
|
160
|
-
export type {
|
|
161
|
-
export type {
|
|
162
|
-
export type {
|
|
163
|
+
export type { CustomCommand, CustomCommandFactory } from "./custom-commands/types";
|
|
164
|
+
export type { CustomTool } from "./custom-tools/types";
|
|
165
|
+
export type { HookAPI, HookCommandContext, HookContext, HookFactory } from "./hooks/types";
|
|
166
|
+
export type { MCPManager, MCPServerConfig, MCPServerConnection, MCPToolsLoadResult } from "./mcp/index";
|
|
167
|
+
export type { Settings, SkillsSettings } from "./settings-manager";
|
|
168
|
+
export type { Skill } from "./skills";
|
|
169
|
+
export type { FileSlashCommand } from "./slash-commands";
|
|
170
|
+
export type { Tool } from "./tools/index";
|
|
163
171
|
|
|
164
172
|
export {
|
|
165
173
|
// Pre-built tools (use process.cwd())
|
|
@@ -278,10 +286,29 @@ export function discoverContextFiles(cwd?: string, agentDir?: string): Array<{ p
|
|
|
278
286
|
/**
|
|
279
287
|
* Discover slash commands from cwd and agentDir.
|
|
280
288
|
*/
|
|
281
|
-
export function discoverSlashCommands(
|
|
289
|
+
export function discoverSlashCommands(
|
|
290
|
+
cwd?: string,
|
|
291
|
+
agentDir?: string,
|
|
292
|
+
settings?: CommandsSettings,
|
|
293
|
+
): FileSlashCommand[] {
|
|
282
294
|
return loadSlashCommandsInternal({
|
|
283
295
|
cwd: cwd ?? process.cwd(),
|
|
284
296
|
agentDir: agentDir ?? getDefaultAgentDir(),
|
|
297
|
+
enableClaudeUser: settings?.enableClaudeUser,
|
|
298
|
+
enableClaudeProject: settings?.enableClaudeProject,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Discover custom commands (TypeScript slash commands) from cwd and agentDir.
|
|
304
|
+
*/
|
|
305
|
+
export async function discoverCustomTSCommands(cwd?: string, agentDir?: string): Promise<CustomCommandsLoadResult> {
|
|
306
|
+
const resolvedCwd = cwd ?? process.cwd();
|
|
307
|
+
const resolvedAgentDir = agentDir ?? getDefaultAgentDir();
|
|
308
|
+
|
|
309
|
+
return loadCustomCommandsInternal({
|
|
310
|
+
cwd: resolvedCwd,
|
|
311
|
+
agentDir: resolvedAgentDir,
|
|
285
312
|
});
|
|
286
313
|
}
|
|
287
314
|
|
|
@@ -555,12 +582,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
555
582
|
const contextFiles = options.contextFiles ?? discoverContextFiles(cwd, agentDir);
|
|
556
583
|
time("discoverContextFiles");
|
|
557
584
|
|
|
558
|
-
// Hook runner - created
|
|
559
|
-
let
|
|
585
|
+
// Hook runner - always created (needed for custom command context even without hooks)
|
|
586
|
+
let loadedHooks: LoadedHook[] = [];
|
|
560
587
|
if (options.hooks !== undefined) {
|
|
561
588
|
if (options.hooks.length > 0) {
|
|
562
|
-
|
|
563
|
-
hookRunner = new HookRunner(loadedHooks, cwd, sessionManager, modelRegistry);
|
|
589
|
+
loadedHooks = createLoadedHooksFromDefinitions(options.hooks);
|
|
564
590
|
}
|
|
565
591
|
} else {
|
|
566
592
|
// Discover hooks, merging with additional paths
|
|
@@ -570,10 +596,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
570
596
|
for (const { path, error } of errors) {
|
|
571
597
|
console.error(`Failed to load hook "${path}": ${error}`);
|
|
572
598
|
}
|
|
573
|
-
|
|
574
|
-
hookRunner = new HookRunner(hooks, cwd, sessionManager, modelRegistry);
|
|
575
|
-
}
|
|
599
|
+
loadedHooks = hooks;
|
|
576
600
|
}
|
|
601
|
+
const hookRunner = new HookRunner(loadedHooks, cwd, sessionManager, modelRegistry);
|
|
577
602
|
|
|
578
603
|
const sessionContext = {
|
|
579
604
|
getSessionFile: () => sessionManager.getSessionFile() ?? null,
|
|
@@ -695,6 +720,14 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
695
720
|
};
|
|
696
721
|
|
|
697
722
|
let allToolsArray: Tool[] = [...builtInTools, ...wrappedCustomTools];
|
|
723
|
+
|
|
724
|
+
// Filter out hidden tools unless explicitly requested
|
|
725
|
+
if (options.explicitTools) {
|
|
726
|
+
const explicitSet = new Set(options.explicitTools);
|
|
727
|
+
allToolsArray = allToolsArray.filter((tool) => !tool.hidden || explicitSet.has(tool.name));
|
|
728
|
+
} else {
|
|
729
|
+
allToolsArray = allToolsArray.filter((tool) => !tool.hidden);
|
|
730
|
+
}
|
|
698
731
|
time("combineTools");
|
|
699
732
|
|
|
700
733
|
// Apply bash interception to redirect common shell patterns to proper tools (if enabled)
|
|
@@ -730,9 +763,17 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
730
763
|
systemPrompt = options.systemPrompt(defaultPrompt);
|
|
731
764
|
}
|
|
732
765
|
|
|
733
|
-
const
|
|
766
|
+
const commandsSettings = settingsManager.getCommandsSettings();
|
|
767
|
+
const slashCommands = options.slashCommands ?? discoverSlashCommands(cwd, agentDir, commandsSettings);
|
|
734
768
|
time("discoverSlashCommands");
|
|
735
769
|
|
|
770
|
+
// Discover custom commands (TypeScript slash commands)
|
|
771
|
+
const customCommandsResult = await loadCustomCommandsInternal({ cwd, agentDir });
|
|
772
|
+
time("discoverCustomCommands");
|
|
773
|
+
for (const { path, error } of customCommandsResult.errors) {
|
|
774
|
+
console.error(`Failed to load custom command "${path}": ${error}`);
|
|
775
|
+
}
|
|
776
|
+
|
|
736
777
|
agent = new Agent({
|
|
737
778
|
initialState: {
|
|
738
779
|
systemPrompt,
|
|
@@ -782,6 +823,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
782
823
|
fileCommands: slashCommands,
|
|
783
824
|
hookRunner,
|
|
784
825
|
customTools: customToolsResult.tools,
|
|
826
|
+
customCommands: customCommandsResult.commands,
|
|
785
827
|
skillsSettings: settingsManager.getSkillsSettings(),
|
|
786
828
|
modelRegistry,
|
|
787
829
|
});
|